I'm a newbie to assembly programming, working through Programming Ground Up on an Ubuntu x86_64 desktop with GNU assembler v2.20.1.
I've been able to assemble/link execute my code, up until I get to using pushl/popl instructions for manipulating the stack. The following code fails to assemble:
.section .data # empty .section .text .globl _start _start: pushl $1 # push the value 1 onto the stack popl %eax # pop 1 off the stack and into the %eax register int $0x80 # exit the program with exit code '1'
Using "as test.s -o test.o", these errors appear on the terminal and test.o is not created:
test.s: Assembler messages: test.s:9: Error: suffix or operands invalid for 'push' test.s:10: Error: suffix or operands invalid for 'popl'
I've checked the documentation, and the operands I'm using for pushl and popl are valid. This isn't exactly a debugging question--so what's wrong with my code? Or is it my assembler?
In 64-bit mode you cannot push and pop 32-bit values; you need pushq
and popq
.
Also, you will not get a proper exit this way. On 32-bit x86, you would need to set %eax
to 1 to select the exit()
system call, and set %ebx
to the exit code you actually wish. On 64-bit x86 (that's what you are using), conventions are different: the system call number for exit()
is 60, not 1; the first system call parameter goes in %rdi
, not %rbx
; the system-call invocation opcode is not int $0x80
but the special, x86-64-only opcode syscall
.
Which leads to:
.section .data .section .text .globl _start _start: pushq $60 popq %rax pushq $1 popq %rdi syscall
(each push
/pop
sequence can be replaced with a simple mov
(like mov $60, %eax
) of course; I suppose that you are trying to explicitly test push
and pop
, optimize for code-size, or avoid 0
bytes in the machine code (for an exploit payload))
Related:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With