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
I ran into this error working through the same book. I created the following shell script (att.sh):
#!/bin/sh
as --32 $1.s -o $1
ld -melf_i386 $1.o -o $1
./$1
echo $?
Which I then made executable and ran (assuming an input file myfile.s):
chmod +x ./att.sh
./att.sh myfile
You may push any value without push command like that
decq %rsp
movb $0, (%rsp)
push 1 byte on stack and pop after
movb (%rsp), %al
incq %rsp
And any other size. As compilator don't generate any error and all will work good! To address may use rbp register instead of rsp. Now is allowed.
You need to replace the push/pop sequence with
pushq $1 # push the value 1 onto the stack
popq %rax # pop 1 off the stack and into the %eax register
Note the error message is "suffix or operand invalid", you only checked the second part of the logical OR
in the error message, maybe because you weren't exactly sure what the suffix means: it's the "l".
Edit: Please see Thomas answer for an explanation why your code won't work anyway even if it assembles.
I recently started following these examples too, I found the following worked:
.code32
to the top of your assembly code--32
flag-m elf_i386
flagYou can see my example here
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: