I am trying to write a test program in AT&T syntax assembly that pushes the ascii value of some characters to the stack, then prints them. My code is as follows:
.text
.global main
main:
push $0
push $10
push $65
mov $4,%eax
mov $1,%ebx
mov %esp,%ecx
mov $3,%edx
int $0x80
mov $1,%eax
int $0x80
What I would expect this program to do is push 0, 10, and 65 to the stack so that the stack is 65, 10, 0 (capital A, new-line, end of string). Set eax
and ebx
to the values for writing to stdout, and setting ecx
to the stack pointer so that it writes what's on the stack, while edx
is the length of what's on the stack(i.e. 3). When I run this, absolutely nothing happens. Can you help me understand what I'm doing wrong and what is actually happening here?
Each push
instruction pushes 4 bytes onto the stack. So, this is how the stack looks like before the int 0x80
:
....
---------- (highest address)
| 0x00 |
----------
| 0x00 |
----------
| 0x00 |
----------
| 0x00 |
---------- <-- push $0
| 0x00 |
----------
| 0x00 |
----------
| 0x00 |
----------
| 0x0A |
---------- <-- push $10
| 0x00 |
----------
| 0x00 |
----------
| 0x00 |
----------
| 0x41 |
---------- <-- push $65 <-- ESP
However, at that moment you would like the stack to look like:
....
----------
| 0x00 |
----------
| 0x0A |
----------
| 0x41 |
---------- <-- ESP
This can be achieved by replacing your push
instructions by the following:
push $0x0a41
That is:
.text
.global main
main:
push $0x0a41
mov $4,%eax ;system call write()
mov $1,%ebx ;file descriptor (stdout)
mov %esp,%ecx ;string
mov $3,%edx ;length of the string
int $0x80
mov $1,%eax
int $0x80
In the edx
register you are already specifying the length of the string (i.e.: 3
), the NUL character is pointless (you are actually sending it to stdout
).