0
votes

Whenever I compile the following program:

.syntax unified
.section .text
_start:
ADD R0, R1

I get the following binary output:

ADD.W R0, R0, R1

which means my assembler transfers the 16 bit code to 32 bit code. I wonder why my assembler behaves like that instead of compiling the code to the 16 bit instruction "08 44"

I run the assembly with the following command:

arm-none-eabi-as -o output.o -m thumb -EL input.s

1
2-byte thumb addition sets the flags. if you write adds r0, r1 you should get a 16-bit instruction. - EOF
that still does not explain why the assembler does not translate ADD R0, R1 to 08 44 - YouYou
it explains it perfectly the register based thumb add instruciton modifies flags, you are asking for a thumb instruction that does not modify the flags (add vs adds) so you have to take the thumb2 instruction if your target supports it o ryou have to use an arm instruction - old_timer
the assembler did what you told it to that is why. If you want it to do something else then tell it to do something else, add without the s can never equal the 0x44xx instruction. then going further since both registers are between r0 and r7 it is very very unlikely that it will ever pick the 0x44xx instruction either. if you want the 0x44xx instruction then tell the assembler to use that by using the right assembly syntax. - old_timer
FWIW, explicitly using the .n suffix would also force the assembler to pick a 16-bit encoding or give an error if it can't. - Notlikethat

1 Answers

2
votes
add r0,r1
adds r0,r1
adds r8,r0

arm-none-eabi-as -mthumb  so.s -o so.o
so.s: Assembler messages:
so.s:2: Error: instruction not supported in Thumb16 mode -- `adds r0,r1'
so.s:3: Error: instruction not supported in Thumb16 mode -- `adds r8,r0'

interesting

add r0,r1
add r0,r1
add r8,r1

00000000 <.text>:
   0:   1840        adds    r0, r0, r1
   2:   1840        adds    r0, r0, r1
   4:   4488        add r8, r1

interesting.

.thumb
.syntax unified

add r0,r1
add r0,r1
add r8,r1

00000000 <.text>:
   0:   eb00 0001   add.w   r0, r0, r1
   4:   eb00 0001   add.w   r0, r0, r1
   8:   4488        add r8, r1

okay progress

.thumb
.syntax unified

add r0,r1
adds r0,r1
adds r8,r1

00000000 <.text>:
   0:   eb00 0001   add.w   r0, r0, r1
   4:   1840        adds    r0, r0, r1
   6:   eb18 0801   adds.w  r8, r8, r1

hmmm.

.thumb
.syntax unified

add r0,r1
adds r0,r1
add r8,r1

00000000 <.text>:
   0:   eb00 0001   add.w   r0, r0, r1
   4:   1840        adds    r0, r0, r1
   6:   4488        add r8, r1

okay that is just disturbing.

.thumb
.syntax unified

add r0,r1
adds r0,r1
add.w r8,r1

00000000 <.text>:
   0:   eb00 0001   add.w   r0, r0, r1
   4:   1840        adds    r0, r0, r1
   6:   eb08 0801   add.w   r8, r8, r1

So getting the 0x18xx and 0x44xx instruction to generate is not to hard. the assembler doesnt make life easy. if you want a specific instruction you should just put the machine code in there and be done with it.

EDIT, sigh tried Notlikethat's suggestion

.thumb
.syntax unified

add.n r0,r1
add.n r8,r1

arm-none-eabi-as -mthumb so.s -o so.o
so.s: Assembler messages:
so.s:5: Error: cannot honor width suffix -- `add.n r0,r1'

fail

.thumb

add.n r0,r1
add.n r8,r1

arm-none-eabi-as -mthumb so.s -o so.o
so.s: Assembler messages:
so.s:4: Error: unexpected character `n' in type specifier
so.s:4: Error: bad instruction `add.n r0,r1'
so.s:5: Error: unexpected character `n' in type specifier
so.s:5: Error: bad instruction `add.n r8,r1'

fail

.thumb
.syntax unified

adds.n r0,r1
add.n r8,r1

00000000 <.text>:
   0:   1840        adds    r0, r0, r1
   2:   4488        add r8, r1

okay that got it...

and the add vs adds, makes sense too, for whatever reason the high register version of the add the 0x44xx one you were after does not modify the flags where the 0x18xx low register one does. The ascii assembly language in the ARMv7-m ARM shows this.

EDIT 2, an older arm arm says

Operand restriction If a low register is specified for and Rm (H1==0 and H2==0), the result is UNPREDICTABLE. So for the armv4 and armv5 I wouldnt try to make your 0x4408 instruction as it is unpredictable.

The armv7-m doc does not say that so in theory okay for that architecture. dont know what the armv6m says.