Reputation: 388
I have this little program written in x64 assembly:
xor rdx,rdx
push rdx ;null terminator
push 0x41414141 ;AAAA
push 0x45454545 ;EEEE
mov rsi,rsp ;pointer to the string
mov rdi,1 ;output file: stdout
mov rdx,8 ;buffer size 8
mov rax,1 ;write syscall
syscall
As you can see, I push eight bytes to the stack and when I call write with buffer size 8, I am expecting to see EEEEAAAA
but the output is EEEE
. However, when I set the buffer size rdx
to 12, I can see the full string EEEEAAAA
. What is between those four-byte blocks? Aren't they ought to be adjacent?
Upvotes: 0
Views: 144
Reputation: 58762
Each push writes 8 bytes, since that is the stack size in 64 bit mode. The immediate in the instruction is sign extended to 64 bits, see the instruction set reference: If the source operand is an immediate of size less than the operand size, a sign-extended value is pushed on the stack.
As such, your stack looks like (from rsp
upwards):
0x0000000045454545 ; EEEE sign extended to 64 bits
0x0000000041414141 ; AAAA sign extended to 64 bits
0x0000000000000000 ; NULL terminator
As workaround you can do:
xor rdx, rdx
push rdx
mov rax, 0x4141414145454545
push rax
mov rsi,rsp ;pointer to the string
mov rdi,1 ;output file: stdout
mov rdx,8 ;buffer size 8
mov rax,1 ;write syscall
syscall
Upvotes: 2