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

关于.short数组奇数偏移处movw至AX与movb至AL加载指令的差异及代码运行结果异常的技术问询

解释x86汇编中movb与movw从.short数组奇数偏移加载的差异

咱们先从你的.short数组在内存里的实际布局说起——x86默认是小端模式,也就是每个多字节数据的低字节存在低地址,高字节存在高地址。你的数组定义是:

arr: .short 1, 0xEA, 0x2, 0x3, 0b1010

转换成内存中的字节序列(按地址从低到高排列)就是:

地址偏移 | 字节值
0x00     | 0x01  ; 第一个.short元素1的低字节
0x01     | 0x00  ; 第一个.short元素1的高字节
0x02     | 0xEA  ; 第二个.short元素0xEA的低字节
0x03     | 0x00  ; 第二个.short元素0xEA的高字节
0x04     | 0x02  ; 第三个.short元素0x2的低字节
0x05     | 0x00  ; 第三个.short元素0x2的高字节
...(后面元素同理)

现在逐个拆解你的指令:

1. movb 3(%rbx),%al

%rbx指向arr的起始地址,3(%rbx)就是从起始地址偏移3字节的位置——对应上面的0x03偏移,字节值是0x00。movb是单字节加载指令,只读取这个位置的1个字节,然后存入8位寄存器%al,所以%al的值自然是0x0。

2. movw arr+3, %ax

arr+3同样是偏移3字节的位置,但movw是16位(字)加载指令,会从这个位置开始连续读取2个字节:偏移3的0x00和偏移4的0x02。

因为x86是小端模式,加载16位值时,低地址的字节会存在寄存器的低8位(%al),高地址的字节存在寄存器的高8位(%ah)。所以这两个字节组合起来就是0x02(高字节) + 0x00(低字节) = 0x200,也就是你看到的%ax的值。


两条指令的核心区别(针对奇数偏移加载.short数组场景)

  • movb 目标地址, %al:只读取目标偏移处的单个字节,完全不关心这个位置是否在.short元素的边界上,直接取这1个字节到8位寄存器。
  • movw 目标地址, %ax:从目标偏移处开始读取连续2个字节(大概率跨了两个.short元素的部分字节),然后按小端规则把这两个字节拼接成16位值存入%ax。简单说就是,它不会校验起始地址是否对齐,只要是16位加载就取连续2字节再组合。

内容的提问来源于stack exchange,提问作者Raea6789

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 17:57:37