I'm currently learning Assembly. I want to write a program which ends up with three variables that point to each other:
0x804a000: 0x804a001 ; 0 -> 1
0x804a001: 0x804a002 ; 1 -> 2
0x804a002: 0x804a000 ; 2 -> 0
According to some other posts, I can retrieve (e. g. for mov
):
- the contents of a variable
x
using[x]
- the address of a variable
x
usingx
Here is what I came up so far:
section .bss
head resd 3 ; reserve three dwords
section .text
global _start
_start:
xor eax, eax
xor ebx, ebx
xor ecx, ecx ; counter = 0
mov eax, head ; move the address of head into eax: eax -> 0
mov ebx, eax ; move the address of head from eax into ebx: ebx -> 0
add ebx, 2 ; ebx -> 2
mov [ebx], eax ; move the value of eax ( = the address of 0 ) into the address in ebx ( = the address of 2)
loop: ; first run second run
inc ecx ; eax -> 0 eax -> 1
mov ebx, eax ; ebx -> 0 ebx -> 1
add eax, 1 ; eax -> 1 eax -> 2
mov [ebx], eax ; 0 -> 1 1 -> 2
cmp ecx, 2 ; ecx = 1 < 2 ecx = 2 == 2
jl loop
mov eax, head ; eax points to the first element
mov eax,1 ; system call number (sys_exit)
int 0x80 ; call kernel
This should basically
0. reserve three dwords, the first of which is at the address in head
- load the address of 0 into
eax
, the address of 2 intoebx
mov [ebx], eax
write the address of 0 into 2 (2 -> 0
)- Repeat the same for fields 0 and 1:
0 -> 1
,1 -> 2
- Store the address of head into eax
Now I assemble and run the whole thing using
nasm -f elf -g -F dwarf test.asm
ld -m elf_i386 -o test.out test.o
However, both the values in 0
and 2
are wrong, as I can check using gdb
:
gdb test.out
(gdb) b 27 // break after mov eax, head
(gdb) r
(gdb) i r eax
eax 0x804a000 134520832 // eax points to head
(gdb) print *134520832
$1 = 77595137 // cell 0 does not point to cell 1
(gdb) print *134520833
$2 = 134520834 // cell 1 does point to cell 2
(gdb) print *134520834
$3 = 134743200 // cell 2 does not point to cell 1
Where do these wrong values come from?
Maybe this happens because I try to write the entire 32bit eax
into the 16bit dword?
I tried changing the lines to mov [ebx], ax
but ended up with the same result.
Another reason I could come up with was that the memory addresses are bigger than a dword
, so I tried to use qword
s instead but ended up with another wrong result.
I also tried using the lea
instruction as sugested in lea assembly instruction, which lead to the same result.
Can someone help me with this? Thanks in advance