I'm trying to call an assembly function from C but I keep getting this error:
(qemu) qemu: fatal: Trying to execute code outside RAM or ROM at 0xfffffffe R00=fffffffc R01=ffffffff R02=00000000 R03=ffffffff R04=00000000 R05=00000000 R06=00000000 R07=00000000 R08=00000000 R09=00000000 R10=00000000 R11=ffffffff R12=00000000 R13=42fffff0 R14=00010060 R15=fffffffe PSR=400001f3 -Z-- T svc32 s00=00000000 s01=00000000 d00=0000000000000000 s02=00000000 s03=00000000 d01=0000000000000000 s04=00000000 s05=00000000 d02=0000000000000000 s06=00000000 s07=00000000 d03=0000000000000000 s08=00000000 s09=00000000 d04=0000000000000000 s10=00000000 s11=00000000 d05=0000000000000000 s12=00000000 s13=00000000 d06=0000000000000000 s14=00000000 s15=00000000 d07=0000000000000000 s16=00000000 s17=00000000 d08=0000000000000000 s18=00000000 s19=00000000 d09=0000000000000000 s20=00000000 s21=00000000 d10=0000000000000000 s22=00000000 s23=00000000 d11=0000000000000000 s24=00000000 s25=00000000 d12=0000000000000000 s26=00000000 s27=00000000 d13=0000000000000000 s28=00000000 s29=00000000 d14=0000000000000000 s30=00000000 s31=00000000 d15=0000000000000000 FPSCR: 00000000 ./mk.sh: line 10: 21664 Aborted (core dumped) qemu-system-arm -M versatilepb -kernel t.bin -nographic -serial /dev/null
Here is my C code:
int g; // un-initialized global int main() { int a, b, c, d, e, f; // local variables a = b = c = d = e = f = 1; // values do not matter g = sum(a, b, c, d, e, f); // call sum(), passing a, b, c, d, e, f }
My assembly code:
.global start, sum start: ldr sp, =stack_top bl main @ call main() in c stop: b stop sum: @ int sum( a, b, c, d, e, f) { return a+b+c+d+e+f; } @ upon entry, stack top contains e, f, passed by main() in C @ Establish stack frame stmfd sp!, {fp, lr} @ push fp, lr add fp, sp, #4 @ fp -> saved lr on stack @ Compute sum of all (6) parameters add r0, r0, r1 @ first 4 parameters are in r0-r3 add r0, r0, r2 add r0, r0, r3 ldr r3, [fp, #4] @ load e into r3 add r0, r0, r3 @ add to sum in r0 ldr r3, [fp, #8] @ load f into r3 add r0, r0, r3 @ add to sum in r0 @ Return to caller sub sp, fp, #4 @ sp = fp-4 (point to the saved FP) ldmfd sp!, {fp, pc} @ return to caller
My linker script:
ENTRY(start) /* Define start as the entry address */ SECTIONS /* program sections */ { . = 0x10000; /* loading address, required by QEMU */ .text : { *(.text) } /* all text in .text section */ .data : { *(.data) } /* all data in .data section */ .bss : { *(.bss) } /* all bss in .bss section */ . =ALIGN(8); . =. + 0x1000; /* 4 KB stack space */ stack_top =.; /* stack_top is a symbol exported by linker */ }
And how I am executing it:
#!/bin/bash arm-none-eabi-as -o ts.o ts.s # assemble ts.s to ts.o arm-none-eabi-gcc -c t.c # compile tc into t.o arm-none-eabi-ld -T t.ld -o t.elf t.o ts.o # link ts.o to t.elf file arm-none-eabi-nm t.elf # show symbols in t.efl arm-none-eabi-objcopy -O binary t.elf t.bin # objcopy t.elf to t.bin qemu-system-arm -M versatilepb -kernel t.bin -nographic -serial /dev/null
What am I doing wrong?
You are missing the "return statement" : ldmfd sp!,{fp,pc}