Ensuring 16-bit THUMB Instruction Encoding for Code Execution from SRAM on STM32F103

I'm working on a project where I want to execute code from internal SRAM on an STM32F103 as an exercise. My goal is to write some THUMB assembly by hand, assemble it using arm-none-eabi-as, load the machine code into SRAM with OpenOCD's mwh command, set the PC to the beginning of SRAM using reg pc 0x20000000, and step through the instructions. The assembly code I wrote is a simple loop:
.thumb
.syntax unified

mov r0, #40
mov r1, #2
add r2, r0, r1
mvn r0, #0x20000000
bx r0
.thumb
.syntax unified

mov r0, #40
mov r1, #2
add r2, r0, r1
mvn r0, #0x20000000
bx r0
Here are the commands I used to assemble and disassemble the code:
$ arm-none-eabi-as -mthumb -mcpu=cortex-m3 -o main.o main.S
$ arm-none-eabi-objdump -d -m armv7 main.o
$ arm-none-eabi-as -mthumb -mcpu=cortex-m3 -o main.o main.S
$ arm-none-eabi-objdump -d -m armv7 main.o
The disassembler output is as follows:
main.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <.text>:
0: f04f 0028 mov.w r0, #40 ; 0x28
4: f04f 0102 mov.w r1, #2
8: eb00 0201 add.w r2, r0, r1
c: f06f 5000 mvn.w r0, #536870912 ; 0x20000000
10: 4700 bx r0
main.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <.text>:
0: f04f 0028 mov.w r0, #40 ; 0x28
4: f04f 0102 mov.w r1, #2
8: eb00 0201 add.w r2, r0, r1
c: f06f 5000 mvn.w r0, #536870912 ; 0x20000000
10: 4700 bx r0
My understanding is that THUMB instructions should be 16 bits long, but the disassembler is showing some instructions (like mov.w r0, #40 as f04f 0028) that are 32 bits. I was expecting 16-bit instructions since I am working with THUMB. Why are some of my instructions encoded as 32-bit THUMB-2 instructions, and how can I ensure that the machine code is 16-bit THUMB-only instructions for loading into SRAM?
2 Replies
Alien Queen
Alien Queen2mo ago
@Sterling You’re seeing 32-bit instructions in your THUMB assembly code disassembly for an STM32F103, even though you expect only 16-bit THUMB instructions. This discrepancy arises because your assembler defaults to using THUMB-2, which includes both 16-bit and 32-bit instructions. you can try this out if your intent on 16bit
.syntax unified
.thumb

movs r0, #40 // 16-bit immediate move
movs r1, #2 // 16-bit immediate move
adds r2, r0, r1 // 16-bit add
mvns r0, #0x28 // 16-bit mvn with 8-bit immediate
bx r0 // Branch exchange
.syntax unified
.thumb

movs r0, #40 // 16-bit immediate move
movs r1, #2 // 16-bit immediate move
adds r2, r0, r1 // 16-bit add
mvns r0, #0x28 // 16-bit mvn with 8-bit immediate
bx r0 // Branch exchange
arm-none-eabi-as -mthumb -mcpu=cortex-m3 -o main.o main.S
arm-none-eabi-as -mthumb -mcpu=cortex-m3 -o main.o main.S
arm-none-eabi-objdump -d -m thumb main.o
arm-none-eabi-objdump -d -m thumb main.o
Sterling
Sterling2mo ago
Alrightt, thanks for this
Want results from more Discord servers?
Add your server