I am fairly new to assembly and architectures so I was playing around with the GCC to assemble my assembler file. I am running Windows 10, with AMD 3750H (IDK if this helps)
It is a fairly simple program, that does the following:
- Creates a stack frame
- Pushes two numbers to the stack
- Pops them one at a time, calling printf once for each. (So the last pop is after the first call)
- exits
Here is the code I wrote:
.data
form:
.ascii "%d\n\0";
.text
.globl main
main:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp;
pushq $420;
pushq $69;
lea form(%rip) , %rcx;
xor %eax, %eax
popq %rdx
call printf
lea form(%rip) , %rcx;
xor %eax, %eax
popq %rdx
call printf
mov %rbp, %rsp
popq %rbp
ret
But the output I get is (rather strangely):
69
4199744
I read about shadow space in the Windows x64 calling convention but I couldn't find the proper way to work with it when using push/pop:
- What is the 'shadow space' in x64 assembly?
- gcc output on cygwin using stack space outside stack frame
This is what I tried (thanks to Jester) and it worked
# subtract 32 when I push
pushq $420;
subq $32, %rsp
# Add 32 when I pop
addq $32, %rsp
popq %rdx
But for some reason I feel there maybe a more elegant way to go about this
Do I have to leave 32 bytes after every push? That seems like a lot of space is being wasted.