簡體   English   中英

具有超過4個寄存器的函數調用ARM匯編

[英]Function call with more than 4 registers ARM assembly

我正在嘗試將r0-r5傳遞到功能check 但是,僅寄存器r0-r3被引用復制。 在我的主要職能中,我有這段代碼。

    push {lr}
    mov r0, #1
    mov r1, #2
    mov r2, #3
    mov r3, #4
    mov r4, #5
    mov r5, #6
    bl check
    pop {lr}
    bx lr

在我的check功能中,我有此代碼。 這在單獨的文件中,也不確定是否重要

    m: .asciz "%d, %d ~ (%d, %d, %d)
    ...
    push {lr}
    ldr r0, =m
    bl printf
    pop {lr}
    bx lr

其輸出為2, 3 ~ (4, 33772, 1994545180) 我正在嘗試學習匯編,所以您可以通過谷歌搜索解釋答案嗎,我知道我需要使用堆棧,但是,我不確定如何使用它,並且想學習如何使用。 提前致謝。

你可以試試看

void check ( unsigned int, unsigned int, unsigned int, unsigned int, unsigned int );

void call_check ( void )
{
    check(1,2,3,4,5);
}

arm-linux-gnueabi-gcc -c -O2 check.c -o check.o arm-linux-gnueabi-objdump -D check.o

00000000 <call_check>:
   0:   e52de004    push    {lr}        ; (str lr, [sp, #-4]!)
   4:   e3a03005    mov r3, #5
   8:   e24dd00c    sub sp, sp, #12
   c:   e58d3000    str r3, [sp]
  10:   e3a00001    mov r0, #1
  14:   e3a01002    mov r1, #2
  18:   e3a02003    mov r2, #3
  1c:   e3a03004    mov r3, #4
  20:   ebfffffe    bl  0 <check>
  24:   e28dd00c    add sp, sp, #12
  28:   e8bd8000    ldmfd   sp!, {pc}

現在當然可以手動優化它,並且仍然可以正常工作。 也許他們將堆棧保持在16字節/ 4字/ 64位邊界上對齊,這是對堆棧指針進行額外的12字節修改的原因嗎? 不知道。 但是除此之外,您還可以看到由於調用另一個函數,您自然需要保存鏈接寄存器。 r0-r3很明顯,然后每個eabi堆棧上的第一件事就是價值第5個字的參數。

同樣,對於您的檢查功能,您可以簡單地讓編譯器開始。 如果看一下代碼,r0作為第一個參數進入,然后通過將其更改為printf的第一個參數來對其進行廢棄。 您需要6個參數來傳遞printf。您需要將它們移到一個參數上。要檢查的第一個參數是printf的第二個參數,要檢查的第二個參數是printf的第三個,依此類推。 因此代碼必須進行這種轉換(其中兩個現在在堆棧中)。

暫無
暫無

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

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