本篇博客介绍汇编语言中常用的语句以及逻辑实现,主要包括:
栈操作pop 和push 算术逻辑操作 跳转指令 标志位指令 有条件传送指令 循环指令 栈操作pop push在每个程序所分配的内存中,划分出一段连续的 区域,作为栈空间:
栈顶指针:保存在%esp寄存器中 压栈操作:push 弹栈操作:pop 示意图:.section .data
value:
.int 0x87654321
.section .text
.global _start
_start:
nop
pushl $0x88888888
#pushw $0x66666666
movl $0x12345678,%ebx
push %ebx
#pushl %ebx
pushw %bx
pushw value
push $value
#pushb %ah
popl %ebx
popl %eax
popw %cx
算术逻辑操作指令
一般算数/逻辑指令
指令 | 功能 |
---|---|
incl | 加1操作 |
ecl | 减1操作 |
SHR | 逻辑右移 |
negl | 取负 |
notl | 取反 |
SHL | 逻辑左移 |
al S, | 加法 |
al S, | 加法 |
subl S, | 减法 |
al S, | 加法 |
SHA | 算术右移 |
imull S, | 乘 |
xorl S, | 异或 |
SAL | 算术左移 |
orl S, | 或 |
anl S, | 与 |
指令 | 功能 |
---|---|
imull S | 有符号乘法——将S与%eax中的值相乘,64位结果的高32位放%ex,低32位放 %eax |
mull S | 无符号乘法——将S与%eax中的值相乘,64位结果的高32位放%ex,低32位放 %eax |
clt S | 将%eax中的值按符号位扩展的方式转换为64位值,高32位放%ex,低32位放%eax |
iivl S | 有符号除法——R[%ex] = R[%ex]:R[%eax] % S; R[%eax] = R[%ex]:R[%eax] / S; |
ivl S | 无符号除法——R[%ex] = R[%ex]:R[%eax] % S; R[%eax] = R[%ex]:R[%eax] / S; |
跳转指令分为直接跳转指令和条件跳转指令,直接跳转指令不需要条件,直接跳转到相应的位置。而条件跳转指令则需要满足相应的条件。
(1)直接跳转 %eip:存放下一条要执行指令的地址 jmp lable:跳转到lable指向的地址 jmp *lable:跳转到lable自身的地址 jmp 0x0804909a :跳转到绝对地址 jmp *%eax :跳转到以%eax为地址的内存所代表的的地址(和jmp %eax等价,但是后者会警告) jump exit:跳转到exit标识出的地址 jump 8exit:跳转到exit自身的地址 代码举例:.section .data
value:
.int 0x87654321
.section .text
.global _start
_start:
nop
movl $0x0804807e,%eax
subl $1,%eax
incl %ebx
jmp exit
incl %eax
jmp *exit
exit: movl $1, %eax
int $0x80
输入指令objdump -d 1014.s,查看代码区,可以看到每一条指令的地址以上的jmp是无条件跳转,如果我么想要有条件跳转,则使用条件跳转指令,规则如下:
条件标识符存储在%eflags寄存器中:
有条件跳转指令如下