ARM function calls are offset by 1 compared to symbol table


I'm trying to compile a minimal ARM cortex M3 example and am seeing a discrepancy I don't understand between the symbol table of my code and the address that the byte code seems to be jumping to.

Startup.s (my minimal assembly code)

.cpu cortex-m3

.global _start
stacktop: .word 0x20001000
.word reset

    mov r0, #6
    mov r1, #7


    rom : ORIGIN = 0x00000000, LENGTH = 0x1000

    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom

If I take these two files and then compile to get an elf and bin file:

arm-none-eabi-as -mcpu=cortex-m3 startup.s -o startup.o
arm-none-eabi-ld -o test.elf -T test.ld startup.o
arm-none-eabi-objcopy test.elf test.bin -O binary

Then, looking at my symbol table with

$ arm-none-eabi-nm test.elf 
00000008 t reset
00000000 t stacktop
00000000 T _start

This makes sense, as I'd expect reset to be at address 0x8 as the only thing before it is the stackpointer stacktop.

However, looking at a hexdump of the binary:

$ hexdump -C test.bin 
00000000  00 10 00 20 09 00 00 00  06 20 07 21              |... ..... .!|

I don't understand why the 5th byte is 0x09. Shouldn't it be 0x08? Indeed, the first command of reset (mov r0 #6) appears at 0x08 so why is the compiler telling the CPU to jump to 0x09? Clearly there's something basic I'm not understanding!

As requested, output from objdump:

$ arm-none-eabi-objdump -d test.elf 

test.elf:     file format elf32-littlearm

Disassembly of section .text:

00000000 <_start>:
   0:   20001000    .word   0x20001000
   4:   00000009    .word   0x00000009

00000008 <reset>:
   8:   2006        movs    r0, #6
   a:   2107        movs    r1, #7
asked on Stack Overflow Aug 22, 2017 by Sam • edited Aug 22, 2017 by Sam

0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0