You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从字节数组加载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:37:35