从字节数组加载EAX后为何与预期字面量比较不相等?
问题分析与修正
你的代码核心问题在于读取数组元素时的寄存器宽度不匹配:
array1用db定义,每个元素是1字节(8位)类型。- 你用32位寄存器
eax读取[array1 + 1],这会从该地址开始连续读取4个字节填充整个eax寄存器,而不是只读取单个元素值2。此时eax中的值是0xXX040302(XX为后续内存的相邻数据),和esi中的2比较自然不相等,因此不会跳转到.equal标签。
修正方案
方案1:使用8位寄存器读取单个字节
直接用8位寄存器(如al,eax的低8位)读取数组元素,再和esi的低8位(sil)比较:
global _start section .data yay: db "It Worked!",0xA array1: db 1, 2, 3, 4 section .bss section .text _start: mov al, [array1 + 1] ; 用al读取单个字节元素 mov sil, 2 ; 用sil存储8位常量 cmp al, sil 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
方案2:零扩展读取字节到32位寄存器
如果需要用32位寄存器操作,使用movzx指令将字节零扩展到32位,确保eax中只包含目标元素的正确值:
global _start section .data yay: db "It Worked!",0xA array1: db 1, 2, 3, 4 section .bss section .text _start: movzx eax, byte [array1 + 1] ; 零扩展字节到32位寄存器eax 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
额外建议
- 操作数组时,务必确保寄存器宽度和数组元素的定义类型匹配:
db对应8位寄存器,dw对应16位,dd对应32位。 - 对于x86汇编,
movzx(零扩展)和movsx(符号扩展)是处理窄数据到宽寄存器的常用指令,能避免读取多余内存数据导致的错误。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

