title: 初识汇编
buchiyexiao
我们作为最后一个小学期汇编课程的年级,在我们之后的汇编就转入到了大学期,也换了老师,但是小学期的汇编课程确实让我感觉到真正学习计算机的一门课程
首先是区别于一些所谓"对抗""实践"之类课程打着实践的名号但是比拼着记忆,就期末考试前谁能把课本背下来谁就能拿满分,平时作业要么就是简单到发指,要么就是浪费时间重复工作,总是会让你感觉到很无语,还会一味的提高考试的分数占比
其次就是汇编是一门我只有第一节课去过,其余都没有去过但是成绩95+的课程,甚至当时还是组队,如何说呢,其实课程并没有很多硬核知识,甚至讲的都是上世纪的东西了,但是更多的是考验一个人的动手能力,虽然有人可能会说,那这样不就会出现无线内卷么,当时我所了解的确实出现内卷,大家都在拼命无效的丰富自己的代码,汇编程序,但是相比于内卷于背课本和一些计算机历史,程序和代码其实更适合"内卷",脱离出固有的"学长学姐的遗产",其实也很大程度上提高了我的代码能力(代码能力也止步于那了
每次作业二选一,前三周每周五查作业,可顺延一次查作业,第二周公布期末大作业(可两人完成),交一个简单的实验报告
20190624
- 汇编语言简介
汇编语言是一门相对低级的语言,使用(近乎)机器语言控制硬件
- CPU单元
-
寄存器:临时存贮器
- 程序计数器PC:记录下一步指令的地址
- 指令寄存器IR: 用于保存当前正在执行的一条指令
- 数据寄存器Data registers: 保存数据
- 地址寄存器Address registers: 保存地址
- 状态寄存器CCR: 两类信息: 一类是体现当前指令执行结果的各种状态信息(条件码),如有无进位(CY位),有无溢出(OV位),结果正负(SF位),结果是否为零(ZF位),奇偶标志位(P位)等;另一类是存放控制信息(PSW:程序状态字寄存器),如允许中断(IF位),跟踪标志(TF位)等。
- 内存地址寄存器MAR: 记录保存数据的内存位置
- 存储缓冲暂存器MBR: 用于充当缓存的寄存器
- CU: 用于记录干什么
-
标志位
- CF:进位标志(Carry Flag)
主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,其值为1,否则为0 - PF:奇偶进位标志(Parity Flag)
反映运算结果最低字节中“1”的个数的奇偶性,偶数个则PF=1,奇数个PF=0 - AF:辅助进位标志(Auxiliary Flag)
AF=1:
在字操作时,发生低字节向高字节进位或借位
在字节操作时,发生低4位向高4位进位或借位
否则AF=0 - ZF:零标志(Zero Flag)
反映运算结果是否为0
运算结果为0,ZF=0,否则ZF=1
判断运算结构是否为0时,可用此标志位 - SF:符号标识(Sign Flag)
反映运算结果的符号位,0正1负 - OF:溢出标志(Overflow Flag)
反映有符号数加减运算所得结果是否溢出(运算结果超多当前运算为数所能表示的范围),溢出OF=1,否则为0
- CF:进位标志(Carry Flag)
-
ADD 加
加法将一个数值加在一个寄存器上或者一个内存地址上
add eax,123 表示 eax=eax+123 -
AND 逻辑与(按位)
ADD 目标数,原数
执行AND指令使OF(溢出)、CF(进位)=0,设置ZF(零)标记 -
CALL 调用
CALL指令将当前的相对地址(IP)压入栈中,并且调用CALL后的子程序
- CALL 404000 —— CALL+地址
- CALL EAX —— CALL寄存器(如果寄存器的值是40400,那与上一种情况等价)
- CALL DWORD PTR [EAX] —— CALL [EAX]偏移量所指向的地址
- CALL DWORD PTR [EAX+5] —— CALL [eax+5]偏移量所指向的地址
-
CMP (比较)
- 语法:CMP op1,op2
- CMP指令比较两个值并且标记CF、OF、ZF:
-
ZF=1,则说明两个数相等,因为zero为1说明结果为0.
-
ZF=0:
- 当无符号时:
- 若CF=1,且cmp进行的是减操作,则说明有借位 ,op1op2
- CF=0,无借位,op1op2
- 当有符号时:
- 若SF=0,OF=0,则说明此时的值为正数,没有溢出,op1op2
- 若SF=1,OF=0,则说明了此时的值为负数,没有溢出,op1op2
- 若SF=0,OF=1,说明了此时的值为正数,有溢出,op1op2
- 若SF=1,OF=1则说明了此时的值为负数,有溢出,可以看出op1op2;
- 当无符号时:
-
DEC (自减)
DEC something
dec用来自减1
使用方式:- dec eax —— eax自减1
- dec [eax] —— 偏移量为eax的值自减1
- dec [401000] —— 偏移量为401000的值自减1
- dec [eax+401000] —— 偏移量为eax+40100的值自减1
dec指令可以标记ZF、OF
-
INC (自加)
可标记ZF、OF -
INT
语法:INT 目标数
INT的目标数必须是产生一个正数,类似于call调用函数,int指令是调用程序对硬件进行控制,不同的值对应不同功能 -
跳转指令和触发条件
跳转指令 | 跳转条件 | 标志条件 |
---|---|---|
JA | 大于 (无符号) | CF=0 and ZF=0 |
JB | 小于(无符号) | CF=1 |
JE | 相等 | ZF=1 |
JG | 大于(有符号) | SF=OF and ZF=0 |
JGE | 大于等于 (有符号) | SF=OF |
JL | 小于(有符号) | SF!=OF and ZF=0 |
JLE | 小于等于(有符号) | SF!=OF |
JMP | 强制跳转 | |
JNE | 不等于 | ZF=0 |
- MOV 传送
- 语法:目的数,源数
- MOV指令将源数赋给目的数,并且源数保持不变
- NOP 不做任何事,在逆向中应用范围最广
- POP
- 语法:POP 目的地址
- 将栈顶的第一个字传送到目的地址。每次POP后,ESP(栈指针寄存器)都会增加以指向新栈顶
- PUSH
- 语法:PUSH 值
- POP的相反操作,将一个值压入栈并且减小栈顶指针以指向新栈顶
- RET (返回)
- 从一个代码区域中推出到调用的CALL指令处
- SUB (减)
- 语法:SUB 目的数,源数
- 源数减目的数,结果储存在目的数中
- 可以标记ZF、OF、CF
- TEST
- 语法:TEST 操作符,操作符
- 主要用于 "TEST EAX,EAX"
- 执行与AND相同的功能,但是并不存储数据。
- 如果EAX=0,则ZF=1
- 如果EAX!=0,则ZF=0