簡體   English   中英

從C調用ARM匯編函數時發生致命錯誤

[英]Fatal error when calling ARM assembly function from C

我正在嘗試從C中調用匯編函數的書中實現一個示例。但是在PC = fffffffe並因此在RAM或ROM之外執行代碼的情況下,我始終遇到致命錯誤。

這是我的C文件tc:

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如何一路走來。 任何幫助,將不勝感激,謝謝!


因此,我簡化了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)

它與PUSHPOP有關 MOV PC,LR替換這兩個程序程序運行並且沒有錯誤。

皮帶

.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}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM