我试图从一本从C调用汇编函数的书中实现一个例子。但是我不断得到一个致命错误,其中PC = fffffffe,因此执行RAM或ROM之外的代码。
这是我的C文件,t.c:
int g; // uninitialized 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
}
我的汇编文件,ts.s:
.global start, sum
start: ldr sp, =stack_top
bl main // call main() in c
stop: b stop
sum: // int sum(int 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-r1
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 at saved FP)
ldmfd sp!, {fp, pc} // return to caller
这是链接描述文件,t.ld:
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 */
}
我使用以下方法汇编文件:
arm-none-eabi-as -o ts.o ts.s
arm-none-eabi-gcc -c t.c
arm-none-eabi-ld -T t.ld -o t.elf t.o ts.o
arm-none-eabi-objcopy -O binary t.elf t.bin
然后执行:
qemu-system-arm -M versatilepb -kernel t.bin -nographic -serial /dev/null
这是输出:
QEMU 2.5.0 monitor - type 'help' for more information
(qemu) pulseaudio: set_sink_input_volume() failed
pulseaudio: Reason: Invalid argument
pulseaudio: set_sink_input_mute() failed
pulseaudio: Reason: Invalid argument
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
Aborted (core dumped)
我是ARM程序集的新手,所以我不确定PC如何一直到fffffffe。任何帮助将不胜感激,谢谢!
所以我已经简化了C和asm文件,但仍然会出现致命错误。
这是更新的C文件:
int g; // uninitialized global
int main()
{
g = sum();
}
ASM文件:
.global start, sum
start: ldr sp, =stack_top
bl main // call main() in c
stop: b stop
sum:
push {lr}
pop {pc}
链接脚本与以前相同。我仍然收到以下错误:
QEMU 2.5.0 monitor - type 'help' for more information
(qemu) pulseaudio: set_sink_input_volume() failed
pulseaudio: Reason: Invalid argument
pulseaudio: set_sink_input_mute() failed
pulseaudio: Reason: Invalid argument
qemu: fatal: Trying to execute code outside RAM or ROM at 0xfffffffe
R00=00000000 R01=00000183 R02=00000100 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=43000004
R12=00000000 R13=43000000 R14=0001000c 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
Aborted (core dumped)
它与 PUSH 和 POP 有关。用 MOV PC,LR 替换这两个程序,程序运行并且没有错误。
答案 0 :(得分:-1)
strap.s
.globl _start
_start:
mov sp,#0x10000
bl main
hang:
b hang
.globl sum
sum:
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-r1
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 at saved FP)
ldmfd sp!, {fp, pc} // return to caller
notmain.c
int sum ( int, int, int, int, int, int );
int g; // uninitialized 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
}
/* memmap */
MEMORY
{
ram : ORIGIN = 0x00010000, LENGTH = 32K
}
SECTIONS
{
.text : { *(.text*) } > ram
.bss : { *(.text*) } > ram
}
arm-linux-gnueabi-as --warn --fatal-warnings -march=armv5t strap.s -o strap.o
arm-linux-gnueabi-gcc -c -Wall -O2 -nostdlib -nostartfiles -ffreestanding -march=armv5t notmain.c -o notmain.o
notmain.c: In function ‘main’:
notmain.c:11:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
arm-linux-gnueabi-ld strap.o notmain.o -T memmap -o notmain.elf
arm-linux-gnueabi-objdump -D notmain.elf > notmain.list
arm-linux-gnueabi-objcopy notmain.elf -O binary notmain.bin
00010000 <_start>:
10000: e3a0d801 mov sp, #65536 ; 0x10000
10004: eb00000b bl 10038 <main>
00010008 <hang>:
10008: eafffffe b 10008 <hang>
0001000c <sum>:
1000c: e92d4800 push {fp, lr}
10010: e28db004 add fp, sp, #4
10014: e0800001 add r0, r0, r1
10018: e0800002 add r0, r0, r2
1001c: e0800003 add r0, r0, r3
10020: e59b3004 ldr r3, [fp, #4]
10024: e0800003 add r0, r0, r3
10028: e59b3008 ldr r3, [fp, #8]
1002c: e0800003 add r0, r0, r3
10030: e24bd004 sub sp, fp, #4
10034: e8bd8800 pop {fp, pc}
00010038 <main>:
10038: e3a03001 mov r3, #1
1003c: e52de004 push {lr} ; (str lr, [sp, #-4]!)
10040: e24dd00c sub sp, sp, #12
10044: e1a02003 mov r2, r3
10048: e58d3004 str r3, [sp, #4]
1004c: e58d3000 str r3, [sp]
10050: e1a01003 mov r1, r3
10054: e1a00003 mov r0, r3
10058: ebffffeb bl 1000c <sum>
1005c: e59f200c ldr r2, [pc, #12] ; 10070 <main+0x38>
10060: e5820000 str r0, [r2]
10064: e1a00003 mov r0, r3
10068: e28dd00c add sp, sp, #12
1006c: e49df004 pop {pc} ; (ldr pc, [sp], #4)
10070: 00010074 andeq r0, r1, r4, ror r0
Disassembly of section .bss:
00010074 <g>:
10074: 00000000 andeq r0, r0, r0
运行它。 ctrl-a然后x退出
qemu-system-arm -M versatilepb -m 128M -nographic -kernel notmain.bin
pulseaudio: pa_context_connect() failed
pulseaudio: Reason: Connection refused
pulseaudio: Failed to initialize PA contextaudio: Could not init `pa' audio driver
QEMU: Terminated
没有错误。
arm-none-eabi-as --warn --fatal-warnings -march=armv5t strap.s -o strap.o
arm-none-eabi-gcc -c -Wall -O2 -nostdlib -nostartfiles -ffreestanding -march=armv5t notmain.c -o notmain.o
notmain.c: In function ‘main’:
notmain.c:11:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
arm-none-eabi-ld strap.o notmain.o -T memmap -o notmain.elf
arm-none-eabi-objdump -D notmain.elf > notmain.list
arm-none-eabi-objcopy notmain.elf -O binary notmain.bin
再次没有错误。
您未提供的示例中缺少哪些部分?
如果你愿意的话,你可以稍微简化一下你的装配,如果你觉得有必要,我可以理解为什么要使用堆叠框架。.globl sum
sum:
push {r3,lr}
add r0, r0, r1
add r0, r0, r2
add r0, r0, r3
ldr r3, [fp, #0x08]
add r0, r0, r3
ldr r3, [fp, #0x0C]
add r0, r0, r3
pop {r3,pc}