为什么LDP在使用w寄存器时会崩溃,而使用x寄存器时不会崩溃

问题描述 投票:0回答:1

在Apply M1的Aarch64汇编上,当将

EXC_BAD_ACCESS
LDP
32位寄存器一起使用时,我收到
w
错误。当我使用
x
64 位寄存器时,不会发生同样的问题。

使用

x
的示例效果很好:

.global _start

_start:
    mov x0, #1 // arg1
    mov x1, #2 // arg2

    stp x0, x1, [sp, #-16]! // push these values to the stack before we branch to another location.

    bl add_nums
    mov x2, x0   // save x0 to w2, so we don't lose once we restore the original x0 from stack

    ldp x0, x1, [sp], #16 // pop off x0, x1 with the values they were before going into add_numbs

    // Exit program
    mov x0, 0       // 0 status code
    mov x16, 1
    svc 0

add_nums:
    // stores the result back to x0, that is why we need to store the original
    // x0 on _start into the stack, so we could restore it later.
    add x0, x0, x1
    ret

有问题的代码。与上一个相同,我只是使用

w
而不是
x
寄存器更新了所有内容,并且堆栈点中修改的范围也是大小的一半:

_start:
    mov w0, #1 // arg1
    mov w2, #2 // arg2

    stp w0, w2, [sp, #-8]! // push these values to the stack before we branch to another location.

    bl add_nums
    mov w2, w0   // save w0 to w2, so we don't lose once we restore the original w0 from stack

    ldp w0, w2, [sp], #8 // pop off w0, w2 with the values they were before going into add_numbs

    // Exit program
    mov x0, 0       // 0 status code
    mov x16, 1
    svc 0

add_nums:
    // stores the result back to w0, that is why we need to store the original
    // w0 on _start into the stack, so we could restore it later.
    add w0, w0, w2
    ret

完整的错误是:

线程#1,队列='com.apple.main-thread',停止原因= EXC_BAD_ACCESS(代码= 259,地址= 0x16fdfe948)

显然A64应该支持

LDP
w
寄存器https://developer.arm.com/documentation/dui0801/l/A64-Data-Transfer-Instructions/LDP--A64-?lang=en

assembly arm64
1个回答
0
投票

感谢 Jester 和 Frank 的评论,现在它变得有意义了。

对于 AArch64,每当使用 sp 访问内存时,sp 都必须是 16 字节对齐。这是由 AArch64 硬件强制执行的 - 参考

这意味着对于 AArch64,即使存储的数据小于该值,堆栈点也必须始终是 16 字节的倍数。否则就会出现那种错误

EXC_BAD_ACCESS

© www.soinside.com 2019 - 2024. All rights reserved.