在Assembly x86上推/弹分段故障

时间:2014-06-09 18:32:46

标签: assembly x86 segmentation-fault stack

我使用 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:抱歉我的英文不好

3 个答案:

答案 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指令将读取堆栈底部的任何内容,并尝试将其用作返回地址 - >砰。

您不能使用堆栈以这种方式返回值。您(例如)需要调用函数为返回数据分配内存并提供它的地址作为参数。阅读有关调用约定和以汇编语言传递参数的信息。