x86汇编movl指令的三条用法差异及第三条功能问询
AT&T语法x86 movl指令差异辨析
你对前两条指令的理解基本准确,这三条指令的核心差异完全来自AT&T汇编语法的寻址规则,第三条的功能需要结合规则才能准确拆解。
要搞懂区别,首先得记住这套语法的核心标记逻辑:
- 操作数顺序固定是「源操作数, 目的操作数」,和Intel语法反过来
- 只要带
$前缀的整数,就是立即数——也就是常量值本身,和内存无关 - 只要带
%前缀的名字,就是寄存器 - 逗号是独立操作数的分隔符,逗号两边是互不影响的源、目的两个独立操作数
- 用括号
()包起来的寄存器/表达式,代表把这个表达式算出来的值当内存地址,直接操作对应的内存位置
接下来逐条拆解:
movl $0x7, %eax
源是带$的立即数7,目的是eax寄存器。作用就是把常量7直接写到eax寄存器里,全程不碰内存。movl $0x7, (%eax)
源还是带$的立即数7,目的是内存——这个内存的地址就是eax寄存器里当前存的那个值。作用是把常量7写到eax值指向的4字节内存位置,整个过程不会改动eax本身存的数值。movl 0x7, (%eax)
这条的结构是逗号分隔的两个独立操作数,没有连写的寻址组合:- 逗号左边的0x7没有带$,也没有括号,属于直接内存寻址:也就是从固定的内存地址0x7处,读一个4字节长的数据当源
- 逗号右边的(%eax)是寄存器间接寻址的内存位置,也就是目的地址是eax当前存的值
整条指令的完整功能是:先从内存0x7地址读出4字节数据,再把这个数据写到eax值指向的4字节内存位置。操作过程既不会改eax寄存器的值,也不会改动0x7地址处原有的内存内容。
很多人容易在这里踩坑:把左边的0x7当成和eax组合的偏移量。如果真的是基址加偏移的寻址,写法一定是0x7和(%eax)连写、中间没有逗号,比如movl %ecx, 0x7(%eax)——意思是把ecx的值写入“eax的值+0x7”计算出来的内存地址,和你写的第三条指令功能完全不一样。
内容的提问来源于stack exchange,提问作者Gaurav
相关产品推荐
相关产品推荐

