我知道OS X是16字节堆栈对齐,但我不太明白为什么它会导致错误。
我在这里所做的就是将对象大小(即24)传递给%rdi,并调用malloc。这个错误是否意味着我要求32个字节?
错误信息是:
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
以下是代码:
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
答案 0 :(得分:3)
就像你说的那样,MacOS X有一个16字节的堆栈对齐,这意味着机器期望堆栈上的每个变量都从当前堆栈指针的16的倍数开始。
当堆栈未对齐时,意味着我们开始尝试从该16字节窗口的中间读取变量,并且通常最终会出现分段错误。
在代码中调用例程之前,需要确保堆栈正确对齐;在这种情况下,意味着基指针寄存器可以被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。
subq $16, %rsp # stack is still aligned
movq %rdi, 16(%rsp) #
... #
callq _malloc # stack is still aligned when this is called, good