You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM编程新手咨询:函数开头需入栈哪些寄存器及参数位置

ARM Assembly Function Basics: Register Stacking & Parameter Passing

Hey there! Great questions—these are core fundamentals for writing reliable ARM assembly code, so let's break them down clearly using the ARM Architecture Procedure Call Standard (AAPCS) (the standard rulebook for how functions interact on ARM systems).

1. Which registers to push onto the stack at the start of a function?

It all comes down to two categories of registers defined by AAPCS: callee-saved and caller-saved registers.

  • Callee-saved registers: These are registers that your function must preserve for the caller. If your function uses any of these, you must push them onto the stack at the start and pop them back off before returning. The callee-saved registers are:

    • r4 to r11 (including fp, which is r11, if you use it to set up a frame pointer)
    • lr (r14, the link register) if your function calls other functions (since lr gets overwritten with the return address of the new call)
    • Note: sp (r13, stack pointer) is always managed carefully, so you don't push it unless you're doing advanced stack manipulation for exceptions.

    Example: If your function uses r4 and sets up a frame pointer, your prologue (start of the function) might look like this:

    push {r4, fp, lr}  ; Save callee-saved registers we'll use
    mov fp, sp         ; Set up frame pointer
    
  • Caller-saved registers: These are r0-r3, r12, and flags. You don't need to save these at the start of your function—whoever called your function is responsible for saving them if they need their values later. You can use these freely without worrying about preserving their original values.

2. Where are function parameters stored?

Again, AAPCS defines this clearly:

  • The first four parameters are passed in registers r0, r1, r2, r3, in order. So the first argument goes to r0, second to r1, etc.

  • Any parameters beyond the fourth are passed on the stack, pushed from right to left (so the 5th parameter is the first one pushed onto the stack before calling the function).

  • For larger types (like structs bigger than 4 bytes, or 64-bit values on 32-bit ARM), there are special rules (e.g., using pairs of registers or allocating stack space), but for most basic cases (integers, pointers), the r0-r3 + stack rule applies.

    Example: If you're calling a function void my_func(int a, int b, int c, int d, int e), the caller would do:

    push {e}           ; Push the 5th parameter first (right-to-left)
    mov r0, a
    mov r1, b
    mov r2, c
    mov r3, d
    bl my_func         ; Call the function
    add sp, sp, #4     ; Clean up the stack parameter
    

    Inside my_func, you'd access r0-r3 for the first four args, and load e from the stack (using the frame pointer or stack pointer).

Also, quick bonus: Function return values are passed back in r0 (and r1 if it's a 64-bit value on 32-bit ARM).

Hope that clears things up—feel free to ask if you want to dive deeper into edge cases!

内容的提问来源于stack exchange,提问作者B3nanana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:36:44