Assembly AT&T汇编语法三类常见操作问题咨询
AT&T 汇编语法常见问题解答
问题1:为什么cmp %eax, $0x2搭配jg goHere的写法不合法?
AT&T 语法下,cmp 指令的双操作数规则为 cmp 源操作数, 目的操作数,执行逻辑是用目的操作数减源操作数,结果仅修改标志位不回存。
该写法不合法的核心原因有两个:
- x86 硬件指令集没有支持「目的操作数为立即数」的
cmp编码,AT&T 语法强制要求双操作数指令中,立即数只能作为第一个(源)操作数出现,你写的代码里第二个操作数是立即数$0x2,直接违反了该编码约束 - 如果要实现「判断0x2是否大于%eax」的逻辑,正确写法为
cmp $0x2, %eax搭配jl goHere,和你已知的调整方案逻辑一致。
问题2:为什么mov $41, %rax合法,mov ($41), %rax不合法?
首先需要明确:AT&T 语法中括号不是无意义的语法修饰,而是内存寻址的标识,括号包裹的内容会被汇编器解析为内存地址的计算表达式,取该地址存储的值参与操作。
mov $41, %rax是将立即数41赋值给寄存器rax,符合「立即数到寄存器」的指令编码规则,自然可以正常编译($41)不符合AT&T语法支持的任何内存寻址格式:AT&T 合法内存寻址的通用格式为偏移量(基址寄存器, 索引寄存器, 缩放因子),括号内仅允许出现寄存器组合,不能直接填立即数,所以汇编器无法解析该写法,直接报错。
如果要实现「读取内存地址41中的值到rax」的需求,正确写法为mov 41, %rax。
问题3:字符串“ABC”存入地址0x100时的存储顺序是怎样的?
字符串属于单字节元素组成的序列,存储顺序和CPU的大小端序无关,永远按照字符的书写顺序从低地址到高地址依次存储:
- 0x100地址存储'A'的ASCII码
0x41 - 0x101地址存储'B'的ASCII码
0x42 - 0x102地址存储'C'的ASCII码
0x43
只有多字节数值类型(比如short、int、long等)的存储才会涉及大小端的字节反转,字符串不需要做反转处理。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

