x86汇编语言复习笔记

0 写在前面

  为了更深入的了解程序的实现原理,近期我学习了IBM-PC相关原理,并手工编写了一些x86汇编程序

  在2017年的计算机组成原理中,曾对MIPS体系结构及其汇编语言有过一定的了解,考虑到x86体系结构在目前的广泛应用,我通过两个月左右的时间对x86的相关内容进行了学习。

  在《x86汇编语言实践》系列中(包括本篇、x86汇编语言实践(1)x86汇编语言实践(2)x86汇编语言实践(3)以及x86汇编语言实践(4)),我通过几个具体案例对x86汇编语言进行实践操作,并记录了自己再编写汇编代码中遇到的困难和心得体会,与各位学习x86汇编的朋友共同分享。

  我将我编写的一些汇编代码放到了github上,感兴趣的朋友可以点击屏幕左上角的小猫咪进入我的github,或请点击这里下载源代码。

  这是《x86汇编语言实践》系列最后一篇文章,后天就要迎来x86汇编的期末考试了,希望所有朋友们以及先先能够考试顺利!

1 基础知识

1.Intel 8086/8088PC机的CPU字长为16位,16位的信息称为1个字,内存的基本单元为1个字节,但任何相邻两个单元都可以组成1个字。Intel 8086/8088PC机共有20根地址线,其寻址范围为00000H~FFFFFH

2.用于间接寻址的寄存器有BX,SP,BP,SI,DI,其中,BX一般用于存放基址;在采用基址变址寻址时,采用SI寄存器,基址寻址默认的段是DS段(DS:[SI]);采用DI寄存器,基址寻址默认的段是ES段(ES:[DI]);采用BP寄存器,基址寻址默认的段是SS段(堆栈的位置和大小是由SP和SS共同决定的)。

3.串操作指令如MOVSB,STOSB,LODSB,SCASB,CMPSB,MOVSW,LODSW,STOSW,SCASW,CMPSW等,源操作数对应的地址是DS:[SI]目的操作数对应的地址是ES:[DI]

4.Intel8086/8088CPU共有9个1为的标志寄存器(标志位),为了便于CPU的加工,他们被组合在一起形成一个16位的程序状态字寄存器PSW中。几个比较重要的标志位有:

  • ZF:当运算结果为0时,ZF=1,否则ZF=0
  • SF:运算结果为负时,SF=1,否则SF=0
  • CF:算术运算最高位产生进位,CF=1.否则CF=0;还用于移位指令保存最高位左移或最低位右移移出的代码。
  • DF:DF=1时每次串操作SI和DI减1,DF=0时每次串操作SI和DI加1。使用CLD可以将DF清零,即规定为正向操作字符串。
  • TF:TF=1时执行完一条产生单步中断,中断处理程序将TF置0。TF标志用于调试。
  • PF,AF,IF,OF这里我斗胆预测一啵,不考(因为真的没有使用过)。

5.STD是将DF置1的指令,与CLD将DF清零的效果相反。使用STD,串指令对应的DI,SI寄存器每次操作后根据是SB还是SW操作自动减少1或2

6.逻辑地址向物理地址的转化(书上P24)。地址转化的动机:20位物理地址无法直接在16位字长的机器中直接运算,因此可以采用Intel的分段方法将其划分为16位段地址和16位段内地址(也称为偏移地址)逻辑地址的基本形式为0000H:0000H,该逻辑地址表示物理地址的00000H。

 那么逻辑地址向物理地址的转换方式可以表述为以下公式:段地址x10H + 偏移地址 = 物理地址

 举例说明:逻辑地址1234H:5678H转换为物理地址为:1234Hx10H + 5678H = 12340H + 5678H = 179B8H。再如:1234H:2001H = 12340H + 2001H = 14341H

7.几个重要的数据传送指令PUSH,POP,PUSHF,POPF

  • PUSH SRC:先SP = SP - 2 再 SS:[SP] <- SRC 
  • PUSHF    :先SP = SP - 2 再 SS:[SP] <- PSW
  • POP   SRC:先SP = SP + 2 再 SRC <- SS:[SP]
  • POPF         :先SP = SP + 2 再 PSW <- SS:[SP]

 总结而言,PUSH和POP是将操作数压(弹)栈,POPF和PUSHF是将PSW标志寄存器压(弹)栈

2 寻址方式

2-1 六种与数据有关的寻址方式

2-1-1 立即寻址

  直接将立即数写到指令中的寻址方式。注意不得超出寄存器的字节范围:AL8位,AX16位。

  【例】

  • AND AX,0FFFEH
  • MOV AL,100H
  • MOV AL,00000101B
  • MOV AX,512

  【不能使用】

  • MOV AL,100H
  • MOV AX,10000H (超出了字节范围)

2-1-2 寄存器寻址

  使用寄存器的寻址方式。可以显示使用,也可以隐式使用。也可以使用段寄存器CS,DS,SS,ES。

  【例】

  • MOV DS,AX 
  • PUSH DS
  • PUSHF (隐式操作PSW)
  • STD (隐式操作PSW)

2-1-3 直接寻址

  直接使用操作数的偏移地址进行寻址的方式,偏移地址用[立即数]的形式表示,或者直接用数据段中定义的变量名表示,或用数据段中定义的变量名+立即数的形式表示。

  【例】

  • AND AX,[0FFFEH]
  • MOV AX,X    ;其中X为数据段中定义好的数据
  • MOV AX,STR+1   ;其中STR为数据段中定义好的数据,STR+1直接寻址到STR下一个字节单元的内容

2-1-4 寄存器间接寻址

  使用寄存器中存储的偏移地址进行寻址。注意只能使用寻址寄存器BX,BP,SI,DI进行寻址,而不能用DX等进行寻址。此外,寻址的地址必须为16位,即不能使用BL等进行寻址。

  【例】

  • MOV AX.[BX]
  • MOV BH,[BP]
  • MOV CX,[SI]
  • MOV DL,[DI]

  以上四条指令等价于

  • MOV AX.DS:[BX]
  • MOV BH,SS:[BP]
  • MOV CX,DS:[SI]
  • MOV DL,ES:[DI]

  但是在每条指令前加上一个段超越的段名,既麻烦又没必要,因此通常都默认缺省为上述隐含段规则。

  【不能使用】

  • MOV AX,[DX]  (不能用DX)
  • MOV DL,[BL]  (必须为16位寻址)

2-1-5 寄存器相对寻址

  在寄存器间接寻址的基础上,再增加一个常偏移量。形式多变,大致有如下几种

  【例】

  • MOV AX,[BX+100]
  • MOV AX,[SI+10H]   <==>  MOV AX,10H[SI]
  • MOV AX,ARRAY[SI]
  • MOV TABLE[DI],AL
  • MOV TABLE[DI+1],AL  3~5展示了立即数也可以是数据段中定义好的变量名

  最终在debug下所有的寻址有效地址会被计算成[DI+XXXX]的形式,XXXX是一个十六进制数。

2-1-6 基址变址寻址

  即基址加变址寻址方式,基址采用BX,BP寻址,变址采用DI,SI寻址,寻址规则相对固定。

  【例】

  • MOV AX,[BX][SI]
  • MOV AX,[BX+SI]
  • MOV ES:[BX+SI],AL
  • MOV [BP+DI],AX   
  • MOV AX,[BX+SI+200]
  • MOV ARRAY[BP+SI],AX

  其中,段取决于基址寄存器,如BX的段就默认为DS;BP缺省为SS。当然,有指定段的情况除外。也可以在两个寄存器加和的基础上再增加一个立即数。

  【不能使用】

  • MOV [BX+CX],AX  (CX不能做变址寄存器)
  • MOV [BX+BP],AX  (BP不能做变址寄存器)
  • MOV [BX+DI],ARRAY  (两个全在内存中的操作数,不符合语法)

2-1 五种与转移地址有关的寻址方式

2-2-1 标号与过程名

2-2-2 段内直接寻址

2-2-3 段内间接寻址

2-2-4 段间直接寻址

2-2-5 段间间接寻址

猜你喜欢

转载自www.cnblogs.com/chrischen98/p/10836078.html
今日推荐