OS X-x64:堆栈未对齐16字节的错误 [英] OS X - x64: stack not 16 byte aligned error
问题描述
我知道OS X是16字节堆栈对齐,但是我真的不明白为什么它在这里引起错误.
I know that OS X is 16 byte stack align, but I don't really understand why it is causing an error here.
我在这里要做的就是将对象大小(为24)传递给%rdi,然后调用malloc.这个错误是否意味着我必须要32个字节?
错误消息是:
libdyld.dylib`stack_not_16_byte_aligned_error: -> 0x7fffc12da2fa< +0>:movdqa%xmm0,(%rsp) 0x7fffc12da2ff< +5>:int3
libdyld.dylib`stack_not_16_byte_aligned_error: -> 0x7fffc12da2fa <+0>: movdqa %xmm0, (%rsp) 0x7fffc12da2ff <+5>: int3
libdyld.dylib`_dyld_func_lookup: 0x7fffc12da300< +0>:pushq%rbp 0x7fffc12da301< +1>:movq%rsp,%rbp
libdyld.dylib`_dyld_func_lookup: 0x7fffc12da300 <+0>: pushq %rbp 0x7fffc12da301 <+1>: movq %rsp, %rbp
这是代码:
Object_copy:
pushq %rbp
movq %rbp, %rsp
subq $8, %rsp
movq %rdi, 8(%rsp) # save self address
movq obj_size(%rdi), %rax # get object size
imul $8, %rax
movq %rax, %rdi
callq _malloc <------------------- error in this call
# rsi old object address
# rax new object address
# rdi object size, mutiple of 8
# rcx temp reg
# copy object tag
movq 0(%rsi), %rcx
movq %rcx, 0(%rax)
# set rdx to counter, starting from 8
movq $8, %rdx
# add 8 to object size, since we are starting from 8
addq $8, %rdi
start_loop:
cmpq %rdx, %rdi
jle end_loop
movq (%rdx, %rsi, 1), %rcx
movq %rcx, (%rdx, %rax, 1)
addq $8, %rdx
jmp start_loop
end_loop:
leave
ret
Main_protoObj:
.quad 5 ; object tag
.quad 3 ; object size
.quad Main_dispatch_table ; dispatch table
_main:
leaq Main_protoObj(%rip), %rdi
callq Object_copy # copy main proto object
subq $8, %rsp # save the main object on the stack
movq %rax, 8(%rsp)
movq %rax, %rdi # set rdi point to SELF
callq Main_init
callq Main_main
addq $8, %rsp # restore stack
leaq _term_msg(%rip), %rax
callq _print_string
推荐答案
就像您说的那样,MacOS X具有16字节的堆栈对齐方式,这意味着计算机希望堆栈上的每个变量都以一个整数倍的字节开始.当前堆栈指针中的16个.
Like you said, MacOS X has a 16 byte stack alignment, which means that the machine expects each variable on the stack to start on a byte that is a multiple of 16 from the current stack pointer.
当堆栈未对齐时,这意味着我们开始尝试从16个字节的窗口的中间读取变量,并且通常会遇到分段错误.
When the stack is misaligned, it means we start trying to read variables from the middle of that 16 byte window and usually end up with a segmentation fault.
在代码中调用例程之前,需要确保堆栈正确对齐;在这种情况下,意味着基址指针寄存器可以被16整除.
Before you call a routine in your code, you need to make sure that your stack is aligned correctly; in this case, meaning that the base pointer register is divisible by 16.
subq $8, %rsp # stack is misaligned by 8 bytes
movq %rdi, 8(%rsp) #
movq obj_size(%rdi), %rax #
imul $8, %rax #
movq %rax, %rdi #
callq _malloc # stack is still misaligned when this is called
要解决此问题,您可以将subq
%rsp
的大小改为16(而不是8).
To fix this, you can subq
the %rsp
by something like 16 instead of 8.
subq $16, %rsp # stack is still aligned
movq %rdi, 16(%rsp) #
... #
callq _malloc # stack is still aligned when this is called, good
这篇关于OS X-x64:堆栈未对齐16字节的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!