(进度:第十二章)
前注
如果再不学的话,以前学的一点汇编就要忘光了(池沼),那么就找一本pdf掩盖过去吧!这篇博客就是理论重要的部分啦,实验有趣的大概也会做出来发博客的吧(心虚)。
正文
- 一个字由两个字节组成,这两个字节分别称为高位字节和低位字节,一个字节由8个bit组成,可以存在8位寄存器中,8086cpu都是16位
- CPU访问内存时由段寄存器提供段地址,8086CPU的四个段寄存器是:CS、DS、SS、ES
- SS:SP始终指向栈顶;CS:IP指向执行的下一条代码;DS存储默认段地址;CX用来记录循环次数
- 载入程序时,CS保存了程序的长度(也是程序返回时的偏移地址),IP为0000h
- 用Debug的R命令查看、改变CPU寄存器的内容:
用Debug的D命令查看内存中的内容;
用Debug的E命令改写内存中的内容;
用Debug的U命令将内存中的机器指令翻译成汇编指令;
用Debug的T命令执行一条机器指令;
用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。
用Debug的G命令执行指令到所指定的IP地址停止。
用Debug的P命令快速执行LOOP循环到结束。 - 常用符号ASCII码值
: 58
[ 91
] 93 - PSP占用10H即256字节,虽然和程序区物理地址相连,但是段地址不同
- 使用p命令执行int 21
- 汇编源程序中,数据不能以字母开头,需要在前面加0
- debug和编译器masm对于[data]有不同解释,debug将其作为一个内存单元,masm将其作为data处理。可以在masm中使用类似于ds:[data]显式地指定内存单元
- mov指令当在寄存器之间时,占两个字节;当在寄存器和立即数之间时,占三个字节(其余指令不建议记,-u查看更好,太多了)
- 要知道assume是伪指令,是由编译器执行的,也是仅在源程序中存在的信息,CPU并不知道它们。我们不必深究assume的作用,只要知道需要用它将你定义的具有一定用途的段和相关的寄存器联系起来就可以了。
- [bx+idata]一次移动两个字节
- si和di是8086中和bx功能相近的寄存器
- 只有bx、si、di和bp四个寄存器可以用于内存单元寻址
- bx、si、di和bp这四个寄存器可以单独出现,或者只能以四种组合出现:bx和si、bx和di、bp和si、bp和di
- 只要在[…]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中。
- 用操作符Xptr指明内存单元的长度,X在汇编指令中可以为word或byte
- push指令只进行字操作
- div指令——除数:有8位和16位两种,在一个reg或内存单元中。被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放(结果在al存放,余数在ah存放);如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位(结果在ax存放,余数在dx存放)。
- dup 用来进行数据的重复
- offset功能是取得标号的偏移地址(CSAPP讲过这个欸)
- jmp word ptr 内存单元地址(段内转移)
- jmp dword ptr 内存单元地址(段间转移)(CS)=(内存单元地址+2)(IP)=(内存单元地址)
- 我们从jcxz的功能中可以看出,“jcxz标号”的功能相当于:if((cx)==0)jmp short标号;
- nop 空操作指令
- ret指令用栈中的数据,修改IP的内容,从而实现近转移;retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移(第一个pop的是IP)。
- call+ret=子程序
- mul指令:8位一个默认放在AL中,另一个放在reg或者内存字节单元中;16位一个默认放在AX中,另一个放在16位reg或者内存字单元中;结果8位在AX中,16位高位在DX中,低位在AX中
- flag寄存器(使用蓝色标出)
- ZF标志位如果指令执行之后结果为0那么zf=1反之zf=0;
- PF标志位,它记录相关指令执行后,其结果中所有bit位的个数是否为偶数,偶数为1奇数为0;
- SF标志位,记录指令执行以后,结果是否为负(默认进行的运算是有符号运算),负数为1,非负为0
- CF标志位记录无符号运算结果的进位值/借位值
- OF标志位记录有符号运算结果是否溢出
- 传送指令、inc指令、loop指令不影响标志位
- adc带进位加法指令 sbb带借位减法指令 cmp比较指令
- 因为溢出导致了实际结果为负(sf值为正),那么真正的结果必然为正,反之亦然
- movsb的功能是将ds:si指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增或递减。df=0增加,df=1减少。(传送的原始位置:ds:si;传送的目的位置:es:di;传送的长度:cx;传送的方向:df。)
- movsw的功能是将ds:si指向的内存字单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2。df=0增加,df=1减少。
- 上面两个指令常配合rep使用,rep表示根据cx的值重复当前命令。
- pushf将标志寄存器的值压栈,popf从栈中弹出数据送入标志寄存器