user3339539
user3339539

Reputation: 305

Push/Pop segmentation fault at Assembly x86

I'm using elf64 to compile my assembly x86 code: I've this sub-routine:

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 

I'm trying to push all digits of a number into my stack using push, but i'm getting segmentation fault. When I comment this line:

 push rdx ; this line generate a segmentation fault

I'll not take "Segmentation Fault" again

I'm using "push rdx" instead of "push EDX" because I'm using 64-bit mode at NASM and when I try to use: "push EDX", I get this error: "instruction not supported in 64-bit mode"

Please, somebody can help tell me why this is happening and how to solve?

PS: Sorry for my bad english

Upvotes: 1

Views: 4080

Answers (3)

Agguro
Agguro

Reputation: 358

I see a push rdx, but nowhere a pop rdx. You keep pushing values on stack and when you reach RET you return to the address which was previously the content of RDX.

Upvotes: 2

PMF
PMF

Reputation: 17185

The instruction

push rdx;

can, on itself, only cause a segmentation fault in rather rare cases: When you're running out of stack or when you've messed around with (E)SP. Since you can run to that code, I don't think you did the second, and the first is rather unrealistic, if this is all your application does. But Michael above pointed to the right direction: It's not the push instruction that's causing the segmentation fault but the missing pops before the ret. At the end of your function, the stack must contain exactly the same number of elements as at the beginning, or the ret instruction will read whatever is at the bottom of the stack and try to use it as return address -> bang.

You cannot use the stack to return values this way. You (for instance) need the calling function to allocate memory for the return data and provide it's address as argument. Read up about calling conventions and passing arguments in assembly language.

Upvotes: 0

Brian Knoblauch
Brian Knoblauch

Reputation: 21349

Shouldn't that be "PUSH EDX" instead of "PUSH RDX"? Or perhaps a PUSH dword ptr 0/PUSH EDX combo if you really need to push 64-bits? Wondering if maybe it ends up being unaligned and doesn't like it? Prior x86 modes don't care about alignment, but perhaps it does for x64 instructions?

Upvotes: 0

Related Questions