.LC0:
.string “Helloworld”
这里的汇编是GNU汇编,即使用AT&T语法的汇编,请不要和别的汇编器混淆。
指令助记符号与伪操作
伪操作
在汇编程序中,以’.’开头的名称并不是指令助记符,不会被翻译为机器码,而是给汇编器的特殊指令,叫做伪操作(实际上是汇编会执行的操作,同时也辅助人们阅读),常见伪操作及其含义如下:
.section及常用段
.section 用于把代码划分为若干段,每个段会被加载至不同地址,同时不同的页面会有相应的操作权限,常见段包括:
名称 | 作用 | 读写/可执行性 |
---|---|---|
.text | 保存代码 | 只读可执行 |
.data | 全局数据段 | 可读可写 |
.rodata | 常量数据段 | 只读 |
.globl
该伪操作的作用是声明全局变量/标号,可供其他源文件在链接时访问,当汇编器编译汇编代码时,会将改变量进行记录,知道其是一个全局变量,当其他文件使用该全局变量时即可提供访问,类似于C语言中的extern语句作用。
.code*
这个操作表示程序要在位模式下运行,\可以是16、32或64,当使用GDB进行调试时,遇到.code会发生架构的切换
1 | (gdb) si |
.set
设置变量,例如下面的语句将PROT_MODE_CSEG的值设置为0x8
1 | .set PROT_MODE_CSEG, 0x8 |
.com
分配空间,在数据段中分配指定空间
1 | .comm stack, KSTACKSIZE |
在数据段中分配KSTACKSIZE长度的空间,这段空间用符号stack来表示。
.align
内存对齐操作
1 | .align 2; /* align function definition 令函数对齐,即其起始地址为2的倍数*/ \ |
函数的起始地址就变成了2的倍数,中间部分会用null补齐。操作数必须是2的整数倍。
常用寄存器及功能
此部分请参考关于寄存器的讲解
常用命令
数据移动类
mov
一下列举了一些mov的使用方法
1 | mov 0x10(%ebp),%edi # ebp+10 --> edi |
mov的变种
根据mov数据长度的不同,mov还有如下变种:
命令名 | 功能 | 备注 |
---|---|---|
movw | 移动2字节(一个word) | mov word |
push
只要有PUSH的动作,ESP寄存器自动减小,push命令使用格式如下:
1 | push %eax |
等价于
1 | subl $4, %esp |
先减小esp,再移动数据。
push的变种
根据push数据长度的不同,push还有如下的变种:
命令名 | 功能 | 备注 |
---|---|---|
pushl | 压入2字节(一个word) | push long |
pushal | push EAX,EBX,ECX,EDX,ESP,EBP,ESI,EDI,一次性压入上述寄存器 | |
下面给出针对push的一个测试代码:
1 |
|
pop
计算类
add
sub
1 | sub $0x1c, %esp # %esp = %esp - 0x1c |
这个语句用于为栈分配空间
test
shl
控制类
转移命令
ljmp
长转移命令,使用格式为:
1 | ljmp addr16 |
call
函数调用命令,使用方式为:
1 | call addr |
等价于
1 | pushl %eip # 先将当前eip保存 |
所以每次调用call,会导致esp减小,因为要将返回地址进行保存。x86架构规定栈向下生长,一个使用call指令的例子如下:
Example instruction | What it does |
---|---|
pushl %eax | subl $4, %esp movl %eax, (%esp) |
popl %eax | movl (%esp), %eax addl $4, %esp |
call 0x12345 | pushl %eip movl $0x12345, %eip |
ret | popl %eip |
ret
函数返回命令,使用方式为:
1 | ret |
该指令等价于
1 | popl %eip |
系统相关
iret
int
IO类
inb
从一个端口读数,读至寄存器
1 | inb $0x64, %al |
从0x64 port读取一个数,然后读至al寄存器中。
附录
符号及功能
符号 | 功能 | 例子 |
---|---|---|
$ | 常量符号,所有常量都必须以$开头 | mov $100, %bx ,将100移植bx |
取地址符号 | movl $values, %edi ,将value所在地址移至edi |
|
% | 寄存器标志,所有寄存器必须以%开头 | mov %ax, %bx |