AT&T汇编语言及其寻址方式
Posted michellel.top
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AT&T汇编语言及其寻址方式相关的知识,希望对你有一定的参考价值。
汇编语言论风格来分主要是两类,一类是Intel汇编,一类是AT&T汇编,分别被Windows和Linux作为主流风格。因为我博客以推荐Linux系统为主,所以以后多以Linux汇编为主要描述语言。
AT&T汇编的特点:
".s"为汇编语言的后缀名,
"#"井号开头的是注释行,
"."点开始的指令一般都是伪指令,
"$"美元符号修饰立即数,
"%"修饰寄存器。例如:
AT&T汇编寄存器,寄存器前需要加上%修饰:
8位:al,ah
16位:ax
32位:eax
64位:rax
AT&T操作符修饰:
8位:b
16位:w
32位:l
64位:q
操作格式:操作符[操作修饰符] 操作对象[源] 操作对象[目标]
寻址方式(Addrsing mode),就是指数据的组织方式,固定格式为:地址或偏移 (%基址或偏移量寄存器, %索引寄存器, 比例因子)
则 最终地址 = 地址或偏移 + %基址或偏移量寄存器 + %索引寄存器 * 比例因子
这一串东西基本上都是可选的,没写的项基本上算以0代替,不同的组合就成了不同的寻址方式,如下:
1) 直接寻址
movl ADDRESS, %eax
ADDRESS其实就相当于"地址或偏移"里的地址,反正就是一个数字。
2)寄存器寻址
其实上面的例子也包括了寄存器寻址,顾名思义%eax就是寄存器寻址,代表对这个寄存器本身的写入或读出。
3)立即寻址
movl $2, %ebx
我一直觉得立即寻址算不算寻址,反正它的意思就是把2这个数字写入%eax寄存器,$2就是立即寻址,其实就是立即数。
4)间接寻址
movl (%eax), %ebx
(%eax)就是间接寻址了,意思就是访问eax寄存器里的数值所代表的地址。相当于通用公式里的%基址或偏移量寄存器。
5)索引寻址(变址寻址)
movl 0xFFFF0000(,%eax,4), %ebx
0xFFFF0000(,%eax,4)就是索引寻址,意思是从0xFFFF0000地址开始,加上%eax * 4作为索引的最终地址。请自行匹配上面的通用公式。
6)基址寻址
movl 4(%eax), %ebx
4(%eax)就是基址寻址,意思是以eax寄存器里的数值作为基址,加上4得到最终地址。也可以匹配到上面的通用公式,而且这个是很常用的寻址方式。
AT&T与Intel的寻址表示不同:
(Intel)sub eax, [ebx + ecx * 4h - 20h]
(AT&T)subl -0x20(%ebx, %ecx, 0x4), %eax
上面表示缩放因子以及偏移量的立即数前不需要加$符号。
总结:Intel的寻址方式若表示为[<base register> + <index register> * <scale> + <offset>],则AT&T表示为:<offset>(<base register>, <index register>, <scale>)
常见汇编指令:
-------------------------------------------------------------------------------------------------------------------------
LEA reg16,mem16 目标地址传送指令: 将一个近地址指针写入到指定的寄存器。
-------------------------------------------------------------------------------------------------------------------------
其中reg16必须是一个16位通用寄存器,mem16必须是一个存储器,执行这个指令后,就将mem16所指的16位偏移地址传送reg16中。
比如: LEA AX,BUF 就是将存储器中BUF所指的地址传送给AX.
区别MOV传送指令: MOV传送的是地址所指的内容,而LEA只是地址。
--------------------------------------------------------------
ADDL 清空堆栈参数
--------------------------------------------------------------
addl source, destination
--------------------------------------------------------------
MOV (X)l w b 传送数据
--------------------------------------------------------------
movx source, destination
--------------------------------------------------------------
CMOV (X)l w b 条件传送数据
--------------------------------------------------------------
cmovx source, destination
EFLAGS位 名称 描述
CF 进位(Carry)标志 数学表达式产生进位或者错位
OF 溢出(Overflow)标志 整数值过大或者过小
PF 奇偶校验(Parity)标志 寄存器包含数学操作造成的错误数据
SF 符号(Sign)标志 指出结果为正还是负
ZF 零(Zero)标志 数学操作的结果为零
指令对 描述 EFLAGS状态
CMOVA/CMOVNBE 大于/小于或者不等于 (CF或者ZF)=0
CMOVAE/CMOVNB 大于或者等于/不小于 CF = 0
CMOVNC 无进位 CF = 0
CMOVB/CMOVNAE 小于/不大于 CF = 1
CMOVC 进位 CF = 1
CMOVBE/CMOVNA 小于或者等于/不大于 (CF或ZF) = 1
CMOVE/CMOVZ 等于/零 ZF = 1
CMOVNE/CMOVNZ 不等于/不为零 ZF = 0
CMOVP/CMOVPE 奇偶校验 PF = 1
CMOVNP/CMOVPO 非奇偶校验/奇偶验 PF = 0
指令对 描述 EFLAGS状态
CMOVGE/CMOVNL 大于或者等于/不小于 (SF异域OF) = 0
CMOVL/CMOVNGE 小于/不大于或者等于 (SF民域OF) = 1
CMOVLE/CMOVNG 小于或者等于/不小于 ((SF异域OF)或ZF) = 1
CMOVO 溢出 OF = 1
CMOVNO 末溢出 OF = 0
CMOVS 带符号(负) SF = 1
CMOVNS 无符号(非负) SF = 0
--------------------------------------------------------------
XCHG 在两个寄存器之间或者存在内存位置之间交换值
--------------------------------------------------------------
cmovx operand1, operand2
--------------------------------------------------------------
BSWP 反转一个32位寄存器中的字节序
--------------------------------------------------------------
常应用于大小端交换
0~7位和24~31位进行交换
8~15位和16~23位交换
bswap %ebx
--------------------------------------------------------------
XADD 交换两个值并把总和存储在目标操作数中
--------------------------------------------------------------
xadd source, destination
--------------------------------------------------------------
CMPXCHG 把一个值和一个外部值进行比较,并且交换它和另一个值
--------------------------------------------------------------
cmpxchg source, destination
--------------------------------------------------------------
CMPXCHG8G 比较两个64位值并且交换它们
--------------------------------------------------------------
cmpxchg8b destination
--------------------------------------------------------------
PUSH (X) l w b 把新的数据项目存到堆栈
--------------------------------------------------------------
pushx source
--------------------------------------------------------------
POP (X) l w b 从堆栈中取回数据
--------------------------------------------------------------
popx destination
指令对 描述
PUSHA/POPA 压入或者弹出所有16位通用寄存器
PUSHAD/POPAD 压入或者弹出所有32位通用寄存器
PUSHF/POPF 压入或者弹出EFLAGS寄存器的底16位
PUSHFD/POPFD
--------------------------------------------------------------
JMP 跳转
--------------------------------------------------------------
jmp location
--------------------------------------------------------------
CALL 调用函数
--------------------------------------------------------------
call address
--------------------------------------------------------------
RET 调用返回指令
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述 EFLAGS
--------------------------------------------------------------
JA 如果大于(above),刚转跳 CF = 0 与 ZF = 0
JAE 如果大于(above)或等于,则转跳 CF = 0
JB 如果小于(below),则转跳 CF = 1
JBE 如果小于(below)或等于,则转跑 CF = 1 或 ZF = 1
JC 如果进位,则转跳 CF = 1
JCXZ 如果CX寄存器为0,则跳转
JECXZ 如果ECX寄存器为0,则跳转
JE 如果相等,则跳转 ZF = 1
JG 如果大于(greater),则跳转 ZF = 0 与 SF = OF
JGE 如果大于(greater)或等于,则跳转 SF = OF
JL 如果小于(less),则转跳 SF<>OF
JLE 如果小于(less)或者小于,则跳转 ZF = 1 或 SF <> OF
JNA 如果不大于(above),则跳转 CF = 1 或 ZF = 1
JNAE 如果不大于(above)或等于,则跳转 CF = 1
JNB 如果不小于(below),则转跳 CF = 0
JNBE 如果不小于(below)或等于,则跳转 CF = 0 与 ZF = 0
JNC 如果无进位,则转跳 CF = 0
JNE 如果不等于,则转跳 ZF = 0
JNG 如果不大于(greater),则跳转 ZF = 1 或 SF<>OF
JNGE 如果不大于(greater)或等于,则跳转 SF<>OF
JNL 如果不小于(less),则跳转 SF = OF
JNLE 如果不小于(less)或者小于,则跳转 ZF = 0 与 SF = OF
JNO 如果不溢出,则转跳 OF = 0
JNP 如果不奇偶校验,则转跳 PF = 0
JNS 如果无符号,则跳转 SF = 0
JNZ 如果非零,则跳转 ZF = 0
JO 如果溢出,则跳转 OF = 1
JP 如果奇偶校验,则转跳 PF = 1
JPE 如果偶校验,则跳出 PF = 1
JPO 如果奇偶校验,则跳转 PF = 0
JS 如果带符号,则跳转 SF = 1
JZ 如果为零,则跳转 ZF = 1
--------------------------------------------------------------
jxx address
--------------------------------------------------------------
CMP 比较指令
--------------------------------------------------------------
cmp operand1, operand2
cmp %eax, %ebx
jeg greater
--------------------------------------------------------------
指令 描述
--------------------------------------------------------------
CLC 清空进位标志(设置它为零)
CMC 对进位标志求反(把它改变为相反的值)
STC 设置进位标志(设置它为1)
--------------------------------------------------------------
--------------------------------------------------------------
INC 递增
--------------------------------------------------------------
--------------------------------------------------------------
DEC 递减
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
--------------------------------------------------------------
LOOP 循环直到ECX寄存器为零
LOOPE/LOOPZ 循环直到ECX寄存器为零,或者没有设置ZF标志
LOOPNE/LOOPNZ 循环直到ECX寄存器为零,或者设置了ZF标志
--------------------------------------------------------------
loop address
--------------------------------------------------------------
MOVZX 用把零值加载到EBX中 (无符号)
--------------------------------------------------------------
EBX:ECX
movzx source, destination
--------------------------------------------------------------
MOVSX 用把零值加载到EBX中 (带符号)
--------------------------------------------------------------
EBX:ECX
movsx source, destination
--------------------------------------------------------------
MOVQ 把数据传送到MMX寄存器中
--------------------------------------------------------------
movq source, destination
--------------------------------------------------------------
MOVDQA/MOVDQU 用于把128位数据传送到MMX寄存器中,或者是MMX寄存器传送数据
--------------------------------------------------------------
movdqa source, destination
--------------------------------------------------------------
FLD 用于把浮点传送入和公传送出FPU寄传器
--------------------------------------------------------------
fld source
--------------------------------------------------------------
FBLD 集把80位打包BCD值加载到FPU寄存器中以及从FPU寄存获取这些值
FBSTP 同上
--------------------------------------------------------------
fbld source
--------------------------------------------------------------
FST 用于获取FPU寄存器堆栈中顶部位置,并且把这个值放到内存位置中
FSTS 同上,单精
FSTL 同上,双精
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
FLD1 把+1.0压入FPU堆栈中
FLDL2T 把10的对数(底数2)压入FPU堆栈中
FLDL2E 把e的对数(底数2)压入FPU堆栈中
FLDPI 把PI值压入FPU堆栈中
FLDLG2 把2的对数(底数10)压入FPU堆栈中
FLDLN2 把2的对数(底数e)压入FPU堆栈中
FLDZ 把+0.0压入FPU堆栈中
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
MOVAPS 把4个对位的打包单精度值传送到XMM寄存器或者内存
MOVUPS 把4个不对准的打包单精度值传到XMM寄传器或者内存
MOVSS 把1个单精度值传送到内存或者寄存器的低双字节
MOVLPS 把2个单精度值传送到内存或者寄存器的低四字节
MOVHPS 把2个单精度值传送到内存或者寄存器的高四字节
MOVLHPS 把2个单精度从低四字传到高四字
MOVHLPS 把2个单精度值从高四字传送到低四字
MOVSHDUP (SSE3) 从内存或者XMM寄存器传送128位值,复制2个和第4个32位数据元素
MOVSLDUP (SSE3) 从内存或者XMM寄存器传送128位值,复制第1个和第3个32位数据元素
MOVDDUP (SSE3) 从内存或者XMM寄存器传送64位双精度浮点值,把它复制到128位XMM寄存器中
--------------------------------------------------------------
--------------------------------------------------------------
指令 转换
CVTDQ2PD 打包双字整数到打包双精度FP(XMM)
CVTDQ2PS 打包双字整数到打包单精度FP(XMM)
CVTPD2DQ 打包双精度FP到打包双字整数(XMM)
CVTPD2PI 打包双精度FP到打包双字整数(XMM)
CVTPD2PS 打包双精度FP到打包单精度FP(XMM)
CVTPI2PD 打包双字整数到打包双精度FP(XMM)
CVTPI2PS 打包双字整数到打包单精度FP(XMM)
CVTPS2DQ 打包单精度FP到打包双字速度(XMM)
CVTPS2PD 打包单精度FP到打包双精度FP(XMM)
CVTPS2PI 打包双精度FP到打包双字整数(XMM)
CVTTPD2PI 打包双精度FP到打包双字整数(XMM,截断)
CVTTPD2DQ 打包双精度FP到打包双字整数(XMM,截断)
CVTTPS2DQ 打包单精度FP到打包双字整数(XMM,截断)
CVTTPS2PI 打包单精度FP到打包双字整数(XMM,截断)
--------------------------------------------------------------
--------------------------------------------------------------
ADD (x) 用于把两个整数相加
--------------------------------------------------------------
add source, destination
-------------------------------------------------------------
ADC (x) 带符号或者无符号整数,
可以把值分割为多个双字数据元素并且对每个元素执行加法操作
-------------------------------------------------------------
adc source, destination
--------------------------------------------------------------
SUB (x) 减法的基本形式
SBB (X) 带借位减法指令
--------------------------------------------------------------
sub source, destination
--------------------------------------------------------------
MUL (x) 无符号乘法
IMUL (x) 带符号乘法
--------------------------------------------------------------
mul source
imul multiplier, source, destination
--------------------------------------------------------------
DIV (x) 无符号除法
IDIV (x) 带符号除法
--------------------------------------------------------------
div divisor
idiv divisor
--------------------------------------------------------------
SAL 向左算述移位
SHL 向左逻辑移位
SAR 移位除法 (符号操作GOOD)
SHR 移位除法 (小心位清0和正负数)
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
ROL 向左循环移位
ROR 向右循环位移
RCL 向左循环移位,并且包含进位标志
RCR 向右循环移位,并且包含进拉标志
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
AAA 调整加法操作的结果
AAS 调整减法操作的结果
AAM 调整乘法作的结果
AAD 准备除法操作的被除数
--------------------------------------------------------------
--------------------------------------------------------------
AND 位与
NOT 位非
OR 位或
XOR 异域
TEST 检查EFLAGS寄存器,
在8位、16位、32位值之间执行接位逻辑AND操作
并且相应地设置符号、零和奇偶校验标志,而且不修改目标值
--------------------------------------------------------------
AND、OR、XOR指令格式
and source, destination
--------------------------------------------------------------
FSTSW 把状态寄存器读取到一个双字内存位置或者AX寄存器中
FSTCW 控制寄存器的设置加载到双字内存位置中查看设置内容
FLDCW 把双字内存值加载到控制寄存器中
FILDS 把一个双字整数值加载到FPU寄存器堆栈中
FISTS 获得寄存器堆栈顶部的值
FIST 助记符指定了S字符
FLDS/FLDL 加载内存中的单精度/双精度值
FST/FSTP 用于把ST0寄存器数据传送到另一个FPU寄存器或者数据从FPU寄存器传送到内存位置
FXCH 交换ST0寄存器和另一个FPU寄存器的值
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
FADD/FADDS 浮点加法/32位
FDIV 浮点除法
FDIVR 反向浮点除法
FMUL 浮点乘法
FSUB 浮点减法
FSUBR 反向浮点减法
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
F2XMI 计算2的乘方(次数为ST0中的值)减1
FABS 计算ST0中的值的绝对值
FCHS 改变ST0中的值的符号
FCOS 计算ST0中的值的余弦
FPATAN 计算ST0中的值的部分反正切
FPREM 计算ST0中的值除以ST1中的值部分余数
FPREM1 计算ST0中的值除以ST1中的值的IEEE部分余数
FPTAN 计算ST0中的值部分正切
FRNDINT 把ST0中的值舍入到最近的整数
FSCALE 把计算ST0乘以2的ST1次乘方
FSIN 计算ST0中的值的正弦
FSINCOS 计算ST0中的值的正弦和余弦
FSQRT 计算ST0中的值的平方根
FYL2X/FYL2X1 计算ST1*log ST0(以2为基数)
FYL2XPI 计算ST1*log(ST0+1)(以2为基数)
FSAVE 把所有FPU寄存器复制到一个108字节的内存位置
,然后初始化FPU状态
FRSTOR 恢复FPU时,所有FPU寄存器(包括数据寄存器)都被复为执行FSAVE指令时的状态
--------------------------------------------------------------
--------------------------------------------------------------
指令 描述
FNCLEX 清空浮点异常标志
FNSAVE 把FPU状态保存到内存中
FNSTCW 保存FPU控制寄存器
FNSTENV 把FPU操作环境保存到内存中
FSTSW 把FPU状态寄存器保存或者保存在AX寄存器中
SAHF 把AH寄存器的第0,2,4,6和7位分别传送到进位、奇偶校验、对准、零和符号标志,
不影响EFLAGS寄存器中的其它位
FLDENV 把内存块的值加载回FPU环境中
--------------------------------------------------------------
--------------------------------------------------------------
MOVSB 传送单一字节
MOVSW 传送一个字(2字节)
MOVSL 传送一个双字(4字节)
--------------------------------------------------------------
--------------------------------------------------------------
STD 用于设置DF标志
CLD 将DF标志清零
--------------------------------------------------------------
--------------------------------------------------------------
REPE 等于时重复
REPNE 不等于时重复
REPNZ 不为零时重复
REPZ 为零时重复
--------------------------------------------------------------
--------------------------------------------------------------
LODSB 把一个字节加载到AL寄存器中
LODSW 把一个字(2字节)加载到AX寄存器中
LODSL 把一个双字(4字节)加载到EAX寄存器中
--------------------------------------------------------------
--------------------------------------------------------------
STOSB 存储AL寄存器中一个字节数据
STOSW 在座AX寄存器中一个字(2字节)的数据
STOSL 在座EAX寄存器中一个双字(4个字节)的数据
--------------------------------------------------------------
1..align abs-expr1, abs-expr2, abs-expr3
.align是存储对齐汇编命令,用于在当前子区中把位置计数器值设置(增加)到下一个指定存储边界处。第1个绝对值表达式abs-expr1(Absolute Expression)指定要求的边界对齐值。对于使用a.out格式目标文件的80x86系统,该表达式值是位置计数器值增加后其二进制值最右面0值位的个数,即是2的幂值。例如,".align 3"表示把位置计数器值增加到8的倍数上。如果位置计数器值本身就是8的倍数,那么就无需改变。但是对于使用ELF格式的80x86系统,该表达式值直接就是要求对齐的字节数。例如".align 8"就是把位置计数器值增加到8的倍数上。
第2个表达式给出用于对齐而填充的字节值。该表达式与其前面的逗号可以省略。若省略,则填充字节值是0。第3个可选表达式abs-expr3用于指示对齐操作允许填充跳过的最大字节数。如果对齐操作要求跳过的字节数大于这个最大值,那么该对齐操作就被取消。若想省略第2个参数,可以在第1和第3个参数之间使用两个逗号。
2..ascii "string"...
从位置计数器所指当前位置为字符串分配空间并存储字符串,可使用逗号分开写出多个字符串。例如,".ascii "Hello world!", "My assembler""。该汇编命令会让as把这些字符串汇编在连续的地址位置处,每个字符串后面不会自动添加0(NULL)字节。
3..asciz "string"...
该汇编命令与".ascii"类似,但是每个字符串后面会自动添加NULL字符。
4..byte expressions
该汇编命令定义0个或多个用逗号分开的字节值。每个表达式的值是1字节。
5..comm symbol, length
在bss区中声明一个命名的公共区域。在ld链接过程中,某个目标文件中的一个公共符号会与其他目标文件中同名的公共符号合并。如果ld没有找到一个符号的定义,而只是一个或多个公共符号,那么ld就会分配指定长度length字节的未初始化内存。length必须是一个绝对值表达式,如果ld找到多个长度不同但同名的公共符号,ld就会分配长度最大的空间。
6..data subsection
汇编语言操作数说明符