Reputation: 305
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
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
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
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