我有以下代码:
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
它打印一个字符,但当我将jmp label_1
添加到label_6
上方一行时,它不会打印任何内容。应该打印字符x
(8*15=120(。ecx
有什么变化吗?
您的内存访问是重叠的:dword
是4个字节,但您正在执行add ecx, 2
和sub ecx, 2
。这意味着您的第二个dword
与第一个重叠。
您的计数器存储在array[0..3]
,并被视为dword
。当您执行add ecx, 2; add dword [ecx], 15
时,您正在触摸array[2..5]
,修改计数器的上两个字节,从0x00000008
变为0x000f0008
。因此,如果你继续这样做,你的代码将在一个无休止的循环中运行。
将您的偏移量更新为4
,您的代码应该可以工作:
...
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
...
旁注:
- 您不需要
cmp dword [ecx], 0
,因为sub dword [ecx], 1
已经设置了由je label_6
检查的零标志。之前的add dword [ecx], 8
设置ZF=0,所以没有问题 - 您的最后一个
exit
系统调用正在退出,返回代码不正确,您可能希望在int 0x80
之前退出xor ebx, ebx
,返回代码为0