资源1:
链接: 汇编语言第三版(王爽)
密码: c3uc
资源2:
ctf学习网址
学习笔记:
***** gcc *****
gcc --save-temps
gcc --verbose
hello.i 预处理之后的文件 [-E]
hello.s 编译之后的汇编文件[-S] [cc1]
hello.o 汇编之后的目标文件[-c] [as]
hello 可执行文件 [-o] [collect2]
collect2链接
5 个重要目标文件 crt1.o、crti.o、crtbeginT.o、crtend.o、crtn.o
3 个静态库 -lgcc、-lgcc_eh、-lc
到程序
############################# 8086 ################################
******** 基本概念 ***********
伪指令
assume cs:code, ds:data, ss:stack
cs指向code段, ds指向data段, ss指向stack段
定义段
data segment
dw 1234h, 4321h....
data ends
stack segment
code segment
定义字符串(define bytes)
db 'foRK' == db 66H, 6FH, 52H, 4BH
十六进制H
十进制D
八进制Q
二进制B
eax 4bytes(32位)
ax 2bytes(16位)
ah, al 1byte(8位)
int
-2147483648 ~ 2147483647
unsigned int
0 ~ 4294967295
.data中
.q 8bytes
.long 4bytes
.short 2bytes
.byte 1byte
.long 1,2,3 12bytes
.zero 10 10bytes
.string "he" 3bytes
dos中一般0:200-0:2ff段空间为空
大小写转换(差20H)
a 61H
A 41H
转换为大写
and al, 11011111B
转换为小写
or al, 00100000B
数据暂存都用堆栈, 不要用寄存器
指明操作数据的长度
mov ax, 1
mov word ptr ds:[0], 1
mov byte ptr ds:[0], 1
ds:1000H ds:1001H
中每个单元代表一个字节(类似于FF)
start:标志在指令执行的开始
end start结束
************ 指令 ************
movb 1byte
movw 2bytes
movl 4bytes
add, sub
inc, dec (+=1, -=1)
imul a,b (b=a*b)(ax(bx,ax)存放结果)
imul a,b,c (c=a*b)
idiv a ([ax(dx,ax)]/a=al(ax)...ah(dx)) dx存高位,ax存低位
and, or, xor, not
neg a (not a +1)
shl, shr
cmp, jle
call, ret (push, pop)
dup (db 3 dup (0,1,2) => db 0,1,2,0,1,2,0,1,2)
offset a 取相对于代码段首地址的偏移
nop占位符,一个字节
lea取偏移
lea ax, [bx] == mov ax, bx
有符号指令:
idiv:带符号除法指令
imul:带符号乘法指令
sal:算术左移指令(保留符号)
sar:右移右移指令(保留符号)
movsx:带符号扩展传送指令
jl:当小于时跳转指令
jle:当小于或等于时跳转指令
jg:当大于时跳转指令
jge:当大于或等于时跳转指令
无符号指令:
idv:除法指令
mul:乘法指令
shl:逻辑左移指令
shr:逻辑右移指令
movzx:无符号扩展传送指令
jb:当小于时跳转指令
jbe:当小于或等于时跳转指令
ja:当大于时跳转指令
jae:当大于或等于时跳转指令
jmp执行的时候修改ip(cs,ip)来实现跳转
jmp short s: (short ip -128~127(8位), 转移时指令码标注的是位移)
jmp near ptr s: (near ip -32768~32767(16位), 转移时指令码标注的是位移)
jmp far ptr s:(转移时指令码标注的是地址)
jmp word ptr ds:[0]: (ip=>ds:[0])
jmp dword ptr ds:[0]: (cs=>ds:[2],ip=>ds:[0])
jcxz s: if(cx == 0){jmp s}else{}
ret(近转移)和retf(远转移)iret(中断返回)
ret == pop ip
retf == pop ip ;pop cs
iret == pop ip; pop cs; popf
call实现调用类似于jmp
1.(根据位移)call s
push ip
ip=ip+-n
2.(根据指令)call far ptr s
push ip(下一条指令的ip)
push cs
cs=s的cs,ip=s的ip
3.(根据寄存器)call ax
push ip
ip=ax的ip
4.(根据内存中的地址)
call word ptr ds:[0]
push ip
ip=ds:[0]
call dword ptr ds:[0]
push ip
push cs
ip=ds:[0], cs=ds:[2]
loop循环,次数由cx决定
mov cx, 11
s:
loop s
adc(ax=ax+bx+cf,用处理计算大数相加进位的问题)
sbb(借位减法)
cmp(减法,不保留结果,影响标志位)
pushf(push flag)
popf(pop flag)
***************** 寄存器 *****************
寄存器ax,bx,cx,dx,ah,al,bh,bl,ch,cl,dh,dl,sp,bp,si,di
段寄存器cs,ds,ss,es
被调用函数可使用: eax,ecx,edx,st0-st7,es,gs,所以调用者先把值压栈保存
不可使用的寄存器: ebx, ebp, esp, edi, esi, cs, ds所以被调用函数开始执行时需要将其保存ret时还原(主程序的堆栈和数据当然不能变)
函数返回存储在eax
cs,ip寄存器
cs*16+ip处读取指令
修改cs:ip内容
jmp 2AE3:3 => cs=2AE3 ip=3
jmp ax => cs不变 ip=ax
push指令修改sp指针使得sp=sp-k(k取决于push寄存器的大小,al取1h,ax取2h,eax取4h)
ds存放数据段基地址
[offset]取数据
1offset代表1byte
取数据ax取2bytes(16位)al取1bytes(8位)
高位在左在下,低位在右在上
ds赋值:
mov bx, 10000H
mov ds, bx
堆栈相关ss,sp,bp
ss:sp表示栈顶
add sp, 2(默认2h)
基址寄存器bp动态改变用来查找栈中元素
si,di和bx功能相近(临时的offset,for中的i)但是不能分成两个8位寄存器
被允许这样写的四个寄存器
[bx]
[si]
[bp]
[di]
[bx+si]
[bx+di]
[bp+si]
[bp+di]
[bx][si]
[bx+si+123]
错误
[bx+bp]
[si+di]
es的作用(ds备用):
ffff:0-ffff:b复制到020:0-020:b中
mov ax, ffffh
mov ds, ax
mov ax, 020h
mov es, ax
mov bx, 0
mov cx, 12
s:
mov dl, [bx]
mov es:[bx], dl
inc bx
loop s
flag寄存器
影响flag寄存器的指令:add,sub,mul,div,inc,or,and等
不影响flag寄存器的指令:mov,push,pop等
zf (zero flag, if(res==0){zf=1}else{zf=0})
pf (1个数为偶数{pf=1}else{pf=0})
sf (if(res<0){sf=1}else{sf=0})
cf (98H+98H=>cf=1 进位,借位标志位) cf设置为0: sub ax, ax
of (if(运算产生溢出){of=1}else{of=0},al=>8bit,ax=>16nit)
cf针对于无符号数,of针对于有符号数
df (if(df==0){add si,1;add di,1}else{sub si,1;sub di,1})
中断
除法错误(0)
单步执行(1)
into命令(4)
int命令(int n)
8086向量表存储在0000:0000-0000:03FF
高位段地址地位偏移地址(各一个字)
中断过程
获取类型码N
TF=0 IF=0
pushf
push cs
push ip
(ip)=4*N (cs)=4*N+2
cld 传输方向为正
rep movsb (move string bytes from ds:[si] to es:[di] repeat cx times)
mov cx,offset posA-offset posB(-为编译器识别的运算符,两个常数的减法)
########################## x64 ###############################
%rsp 被用来作为栈指针
%rax 作为一个函数的返回值
%eflag
byte->long,字符扩展
movsbl %al, %edx
long->q,0扩展
movzlq %eax, %rbx
long->q,ebx高位隐式扩展
mov %ebx, %ebx