我使用 elf64 编译我的程序集x86代码: 我是这个子程序:
printNumber:
mov EAX, EDX ; EDX contain some value like "35"
mov ESI, 10 ; to divide by 10
MOV ECX,0 ; counter
whileDiv:
cmp EAX, 0
je endWhileDiv
xor rdx, rdx ; clean RDX
idiv ESI ; EAX=EAX/10 and EDX = EAX%10
push rdx ; this line generate a segmentation fault
add ECX, 1; count how many items i has added into stack
jmp whileDiv
endWhileDiv:
ret
我试图使用推送将数字的所有数字推入我的堆栈,但我得到了分段错误。 当我评论这一行时:
push rdx ; this line generate a segmentation fault
我不会采取"分段错误"再次
我正在使用" push rdx"而不是"推EDX"因为我在NASM使用64位模式 当我尝试使用:"推送EDX"时,我收到此错误:" 64位模式不支持指令"
拜托,有人可以帮我告诉我为什么会这样,以及如何解决?
PS:抱歉我的英文不好
答案 0 :(得分:1)
我看到了一个推送rdx,但没有一个pop rdx。您继续在堆栈上推送值,当您到达RET时,您将返回之前为RDX内容的地址。
答案 1 :(得分:0)
不应该是" PUSH EDX"而不是" PUSH RDX"?或者如果你真的需要推64位,可能是PUSH dword ptr 0 / PUSH EDX组合?想知道它是否可能最终未对齐并且不喜欢它?之前的x86模式并不关心对齐,但也许它适用于x64指令?
答案 2 :(得分:0)
指令
push rdx;
本身只会在相当罕见的情况下导致分段错误:当你用完堆栈时或者当你用(E)SP乱搞时。既然你可以运行那个代码,我就不会认为你做了第二个代码,而第一个代码是不切实际的,如果这是你的所有应用程序的话。但迈克尔上面指出了正确的方向:它不是导致分段错误的推送指令,而是ret
之前丢失的弹出指针。在函数结束时,堆栈必须包含与开头完全相同数量的元素,或者ret指令将读取堆栈底部的任何内容,并尝试将其用作返回地址 - >砰。
您不能使用堆栈以这种方式返回值。您(例如)需要调用函数为返回数据分配内存并提供它的地址作为参数。阅读有关调用约定和以汇编语言传递参数的信息。