Assembly Basic Notes
Assembly Execution Model
Load-ALU-Store 模式 - 读入寄存器,算术逻辑单元运算,回写至内存
Tools
GCC
gcc -01/-02/-03 source.c—— 编译优化等级gcc -S source.c—— 编译成汇编代码(文本文件)gcc -o source.c—— 编译成 Object 代码(二进制文件)
GDB
si单指令执行x/i $pc执行 si 命令时打印汇编代码disas显示汇编代码bt查看函数堆栈step1下一条汇编指令info registerx /numsizeformat $pc/rsp/rbp
MASM
masm /Zi/Zd src dist
masm /I(path) // 引用 标准库/宏
masm /I..\include
LINK
link /DEBUG src
TD
tab切换分区alt功能键ctrl子功能键
Basic
F2: breakF7: step intoF8: step over
Alt
Alt+F5: 临时跳转至 dos 界面Alt+Enter: 全屏Alt+X: 退出
代码区
<C-A>Assemble: 临时修改汇编指令<C-C>Caller : 从子程序处跳回至 Caller 处<C-F>Follow : 查看 CALL/JMP/INT 跳转至的子程序处<C-O>Origin : 跳转至 cs:ip 指向指令处
数据区
<C-C>Change: 临时修改数据<C-D>Display: 选择显示格式 e.g Byte/Word/Long/Comp/Float/Real/Double/Extended<C-G>Goto: 跳转至指定地址区
NMAKE
$<: 源文件名$?: 所有源文件名$@: 全路径的目标文件$*: 除去扩展名的全路径的目标文件
EXE = $(NAME).exe
OBJS = $(NAME).obj
SRCS = $(NAME).asm
SIMPLE_MODE = ;
LINK_FLAG = /subsystem:windows
ML_FLAG = /c/coff/Zi
MASM_FLAG = /Zi/Zd
$(EXE): $(OBJS)
link $(LINK_FLAG) $(OBJS) $(SIMPLE_MODE)
$(OBJS): $(SRCS)
masm $(MASM_FLAG) $(SRCS) $(SIMPLE_MODE)
clean:
del *.obj
del *.tr
test:
td $(EXE)
Objdump
AT&T反汇编工具
位运算
^:无进位p && *p++: NULL 检查
编码:2^n e.g 一副牌的编码 2 位牌色位+4 位数字位
Address
mov
movX src dest #X:b/w/l/q (1/2/4/8 字节)
address
D(Rb, Ri, S):MEM[ Reg[Rb] + S * Reg[Ri] + D].leal命令:leal D(Rb, Ri, S) dest- 将地址模式表达式的址存入 dest. 作用为快速给指针赋值p = &x[i]即Mem[Reg[x] + i * size]->(x, size, I), 快速计算二次多项式x + i * k.
常用命令
读取指令
mov 读取
内存数据重复读入寄存器 - 使得汇编代码与上下文无关,减少 BUG 产生可能性
R1 = MEM[SP + 8]
……
R1 = MEM[SP + 8]
……
R1 = MEM[SP + 8]
……
算术命令
转移命令
-
Flags
- CF:Carry Flag(unsigned) 进位标志——当有进位时设为 1
- OF:OverFlow Flag(signed) 溢出标志——当补码溢出时设为 1
- SF:Sign Flag(signed) 符号标志——当
t < 0时设为 1 - ZF:Zero Flag 零标志——当
t == 0时设为 1
-
cmpX 命令
cmpl Src2, Src1根据 Src1 – Src2(subl Src2, Src1)的结果设置标志寄存器的值 -
testX 命令
testl Src2, Src1根据 Src1 & Src2(andl Src2, Src1)的结果设置标志寄存器的值e.g testl %eax, %eax 实现符号函数
-
setX 命令 根据标志寄存器运算值,将值存入 dest
setX dest
Control Flow Statement
If Statement
cmovC src, dest(C 表示 Conditional——e/ne 等)
当条件成立时,src->dest src 与 dest 可分别用于存放两种情况的值
Loop Statement
Do While Statement
While Do Statement
For Statement
Switch Statement
Jump Table:
break; → leave
ret
- fallThrough(without break)
- mixing(连冒号)
- missing case
Stack Frame
# 准备阶段
# Caller-Save: %eax %ecx %edx
# Callee-Save: %ebx %esi %edi
# 传参顺序: rdi, dsi, rdx, rcx, r8, r9, stack
pushl %ebp
movl %esp, %ebp
pushl %ebx
# 结束阶段
movl -4(%ebp), %ebx
movl %ebp, %esp
popl %ebp
ret
Data Structure
Arrays
int get_sea_digit(int index, int dig) {
return sea[index][dig];
}
# 访问二维数组元素
# %ecx = dig
# %eax = index
leal 0(,%ecx,4), %edx # 4 * dig
leal (%eax,%eax,4), %eax # 5 * index
movl sea(%edx,%eax,4), %eax # * (sea + 4 * dig + 20 * index)