程序集NASM x64 JMP未按预期工作



我有以下代码:

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, 2sub 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

最新更新