汇编intel与att
汇编有两种语法标准, 分别是intel, att语法
intel语法对应, intel x86_x64体系, x86系列CPU上
att语法对应, gcc objdump 默认格式, 多种CPU上可用(x86, power, VAX)
编译器有
- gasm: .s文件
- nasm: .asm文件
- masm: .asm文件
- fasm: .asm文件
intel att 区别
https://blog.csdn.net/goodcrony/article/details/92794938 ATT与Intel汇编代码格式
指令名
Intel, 内存操作数前用前缀byte prt
, word ptr
, dword ptr
表大小
ATT, 指令都有字符后缀b, w, l
, 表内存操作数的大小
Intel是
mov al, byte ptr foo
AT&T是movb $foo, %al
movb
传送字节 (1 B = 8 bit)movw
传送字 (2 B = 16 bit)movl
传送双字 (4 B = 32 bit)
因为在许多机器上, 32位数都称为长字(long word)
指令顺序
Intel右->左
ATT左->右
Intel是
mov dst, src
ATT是mov src, dst
寄存器名字, Intel不用前缀%
Intel是
esp
ATT是%esp
寄存器中值 = 地址
Intel是
dword ptr [ebp+8]
ATT是8(%ebp)
立即数, Intel不用前缀$
Intel十六, 二进制后缀h
和b
ATT十六进制立即数前缀0x
十进制数
Intel是123
ATT是$123
十六进制数
Intel是123h
ATT是$0x123
ATT直接跳转, (跳转目标: 指令内一部分编码)
jmp Label_1
ATT间接跳转, (跳转目标: 寄存器R, 存储器M中的值[代码地址])
‘*’后为操作数
jmp *%eax
寄存器%eax中的值 = 跳转目标jmp *(%eax)
%eax中的值 = 存储器M地址, 存储器M中的值 = 跳转目标
远跳转和远调用
ATT是
ljmp/lcall section,section,offset
Intel是jmp/call far section:offset
远返回
ATT是
lret $stack-adjust
Intel是ret far stack-adjust
Intel可多代码段程序
ATT不用多代码段程序, UNIX要求所有代码一个段seg
gasm
已有c文件
1 |
|
对应gcc, 通过c文件, 生成s文件
1 | dassein@pad:~/nasm_pjt$ gcc -E area_2019_sep_24.c > area_2019_sep_24.i |
z直接通过c生成可执行文件
1 | gcc -c area_2019_sep_24.c -o area_2019_sep_24 |
生成s文件
1 | .file "area_2019_sep_24.c" |
nasm
用c2nasm.bash反汇编nasm已有c文件1
./c2nasm.bash area_2019_sep_24.c
自动生成area_2019_sep_24.asm
1 | default rel |
附录: c2nasm.bash
先把objconv程序放到/bin中, 供cmd使用obconv
1 |
|