Intel汇编语言中XCHG指令工作原理及代码执行结果疑问
Intel汇编XCHG指令详解及你的代码疑问解答
1. XCHG指令的工作原理
XCHG是Exchange的缩写,说白了就是交换两个操作数的内容,是Intel汇编里专门用来快速做数据交换的指令。它支持几种常见的使用场景:
- 寄存器与寄存器交换:比如
xchg eax, ebx,执行后eax和ebx里的值会完全互换 - 寄存器与内存单元交换:比如
xchg eax, [0x12345678],会把eax中的值和内存地址0x12345678指向的内容互换 - 注意:它不能直接交换两个内存单元的值,必须借助寄存器中转(比如先把第一个内存值读到寄存器,再用XCHG和第二个内存交换)
另外,XCHG在单处理器环境下会自动保证内存操作的原子性,不过这是附加特性,核心功能还是值的交换。
2. 你的代码疑问解答
先把你的代码和预期/实际情况理清楚:
; 前提:arrayD为DWORD类型数组,初始值为[1, 2, 3] mov eax, arrayD ; 注释:eax=1 xchg eax, [arrayD+4] ; 注释:eax=2,arrayD变为[2,1,3]?
你疑惑为什么执行后数组不是[1,1,3]?咱们一步步拆解正确的执行逻辑,就能找到问题所在:
正确的执行流程
mov eax, arrayD:在MASM(微软宏汇编)语法中,直接使用数组名arrayD等价于直接寻址[arrayD],也就是取数组第一个元素(arrayD[0])的值,所以eax被赋值为1,这部分你的注释是对的。xchg eax, [arrayD+4]:DWORD类型每个元素占4字节,所以arrayD+4指向的是数组的第二个元素arrayD[1],它的初始值是2。XCHG的作用是完全交换两个操作数的值:- 把eax里的1写入
arrayD[1]的位置 - 把
arrayD[1]里的2读取到eax中
- 把eax里的1写入
- 最终结果:数组应该变为
[1, 1, 3],eax的值变为2。
为什么你得到了[2,1,3]?
如果你的实际结果是数组变成[2,1,3],那大概率是你对指令的写法或者汇编器语法有误解:
- 可能性1:你把
mov eax, arrayD写成了mov eax, OFFSET arrayD,这时候eax里存的是数组的起始地址(而不是第一个元素的值),后续XCHG交换的是地址值和arrayD[1]的2,这显然会导致错误的结果,但你的注释里说eax=1,所以这个可能性不大。 - 可能性2:你误把XCHG的操作对象写成了
arrayD(也就是xchg eax, arrayD),这时候交换的是eax(1)和arrayD[0](1),结果数组不变,但这也不会得到[2,1,3]。 - 可能性3:你混淆了数组的索引偏移,比如误以为
arrayD+4是第一个元素?但DWORD的偏移是4字节对应一个元素,第一个元素的偏移是0,第二个是4,这点没错。
最可能的情况是你在测试时的代码和你写出来的不一致,或者对结果的观察有误。按照你给出的代码,正确结果应该是数组变为[1,1,3],而不是[2,1,3]。
内容的提问来源于stack exchange,提问作者Alloysius Goh
相关产品推荐
相关产品推荐

