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
正如您所说,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 $16, %rsp # stack is still aligned
movq %rdi, 16(%rsp) #
... #
callq _malloc # stack is still aligned when this is called, good
我在不同的地方读到过这样做是出于“性能原因”,但我仍然想知道这种16字节对齐方式在哪些特定情况下提高了性能。或者,无论如何,选择它的原因是什么。 编辑:我认为我写这个问题的方式有误导性。我不是在问为什么处理器使用16字节对齐的内存会更快,这在文档中随处都有解释。相反,我想知道的是,强制的16字节对齐如何优于在需要时让程序员自己对齐堆栈。我这样问是因为根据我在汇编方面的经验,堆栈强制有两个问题:它只
问题内容: 我试图清楚地了解谁(调用方或被调用方)负责堆栈对齐。64位汇编的情况很清楚,它是由 caller进行的 。 参考系统V AMD64 ABI,第3.2.2节 堆栈框架 : 输入参数区域的末尾应在16(如果在堆栈上通过__m256,则为32)字节边界对齐。 换句话说, 应该 安全地假设,对于被调用函数的每个入口点: 保持(额外的八个是因为隐式将返回地址压入堆栈)。 在32位世界中的外观(假
我在学Windows上的汇编,想弄清楚栈上的值是什么。< br > Visual C #文档说明高于RSP的值是: 分配空间 保存了RBP 返回地址 注册主页(RCX、RDX、R8、R9) 函数参数 问题是堆栈中有32个额外的字节,文档中没有提到。 在内存快照中,RSP从0x0000000000DAF5E0开始。彩色框为: 黄色:两个值为9的64位变量 白色:保存旧RBP返回地址 蓝色:函数参数
输入=堆栈数 但是你只能弹出输入,你不能推到它。输出也是另一个堆栈,你可以返回并推到它,但不能弹出 所以如果 由于您无法在中返回到
我试图清楚地了解谁(调用者或被调用者)负责堆栈对齐。64位程序集的情况相当清楚,它是由调用者完成的。 参考System V AMD64 ABI,第3.2.2节堆栈框架: 输入参数区域的末尾应在16(32,如果__m256在堆栈上传递)字节边界上对齐。 换句话说,应该可以安全地假设,对于被调用函数的每个切入点: 保持(额外的8是因为调用隐式地将返回地址推送到堆栈上)。 它在32位世界中看起来如何(假
问题内容: 下面给出的代码显示了运行时的Stackoverflow错误。但是,如果我使另一个类CarChange创建Car的对象,它将成功运行。我是一个初学者,请执行以下代码以了解在Java中进行向上转换的重要性。 问题答案: 一个stackoverflow通常意味着您有一个无限循环。 收到此消息的原因是因为您从testdrive方法调用驱动器,并且在该方法中再次调用drive。