我是装配新手,正在尝试使用数组。然而,当我尝试将数组值与存储在寄存器中的常量进行比较时,我被抓住了。
从下面的代码中,我期望程序在比较后跳转,因为数组中的值似乎与 esi 中的文字匹配。我的代码如下。
global _start
section .data
yay: db "It Worked!",0xA
array1: db 1, 2, 3, 4
section .bss
section .text
_start:
mov eax, [array1 + 1]
mov esi, 2
cmp eax, esi
je .equal
jmp _done
.equal:
mov eax, 4
mov ebx, 0
mov ecx, yay
mov edx, 11
int 0x80
jmp _done
_done:
mov eax, 1
mov ebx, 0
int 0x80
任何有关我的代码中的错误的建议也非常感谢!
您的代码未正确地将位于数组第一个索引处的值加载到
EAX
中的原因是因为数组在汇编中的含义。在汇编中,当您定义“数组”时,您只是将数据放入内存中。虽然这看起来很明显,但这也意味着元素之间没有分隔符(“字符串”也是一个数组)。这意味着当您执行 MOV EAX, [ARRAY1 + 1]
而不指定操作的大小时,nasm 会查看指令的上下文来延迟大小。由于您使用的是 32 位寄存器,因此大小默认为 DWORD
。这意味着该指令将从 [ARRAY1 + 1]
开始从数组加载 32 位(4 字节)。为了防止这种情况,您需要通过执行 MOVZX EAX, BYTE [ARRAY1 + 1]
将操作的大小指定为字节。您需要使用 MOVZX
将寄存器的其余部分填充为零。
关于您的代码,让我印象深刻的第一件事是在您要跳转的标签之前使用
JMP
。这是不必要的,因为执行将继续到标签中。这是因为标签不是“函数”,而只是表示内存地址的标记。它们不存在于汇编程序中。其次,虽然不重要,但执行 MOV EAX, 0
比执行 XOR EAX, EAX
稍快一些。最后,你有一个空的 BSS
部分,链接器不需要它,可以省略(至少对于 ld 来说)。