I have the following code:
section .data
array times 1024 DW 0
section .text
global _start
_start:
mov ecx, array ; Store the ponter to the first array element
; ---- ADD ----
add dword [ecx], 8
label_1:
cmp dword [ecx], 0
je label_6
; ---- P UP ----
add ecx, 2
; ---- ADD ----
add dword [ecx], 15
; ---- p DOWN ----
sub ecx, 2
; ---- SUB ----
sub dword [ecx], 1
label_6: ; ---- P UP ----
add ecx, 2
mov eax, 4 ; stdout
mov ebx, 1 ; sys_write
mov edx, 1 ; Lenth
int 0x80 ; Call karnel
mov eax, 1 ; system call number (sys_exit)
int 0x80 ;call kernel
It prints a char, but when I add jmp label_1 one line above label_6 it doesn't print anything. It is supposed to print the char x (8 * 15 = 120). Is something changing ecx?
CodePudding user response:
Your memory accesses are overlapping: a dword is 4 bytes, but you are doing add ecx, 2 and sub ecx, 2. This means that your second dword is overlapping with the first one.
Your counter is stored at array[0..3], and is treated as a dword. When you do add ecx, 2; add dword [ecx], 15 you are touching array[2..5], modifying the upper two bytes of your counter, which goes from 0x00000008 to 0x000f0008. Your code will therefore pretty much run in an endless loop if you keep doing this.
Update your offsets to be 4 and your code should work:
...
label_1:
cmp dword [ecx], 0
je label_6
; ---- P UP ----
add ecx, 4
; ---- ADD ----
add dword [ecx], 15
; ---- p DOWN ----
sub ecx, 4
; ---- SUB ----
sub dword [ecx], 1
jmp label_1
label_6: ; ---- P UP ----
add ecx, 4
...
Side notes:
- You don't need
cmp dword [ecx], 0as thesub dword [ecx], 1already sets the zero flag, which is checked byje label_6. The previousadd dword [ecx], 8sets ZF=0 so no problem. - Your final
exitsyscall is exiting with a bad return code, you probably wantxor ebx, ebxbeforeint 0x80to exit with code0.
