时光地下铁

走走停停,看看风景

0%

8086汇编常用知识手册

8086 16位CPU 80386 32位CPU(王爽 《汇编语言》)
AT&T汇编(Mac,iOS模拟器)
ARM汇编 (嵌入式,iOS设备)

基础知识小结

(1)汇编指令是机器指令的助记符,同机器指令一一对应
(2)存储器中指令和数据没有区别,都是二进制信息
(3)存储单元从零开始顺序编号
(4)一个存储单元可以存储8个bit,即8位二进制数
(5)1Byte = 8bit 1KB = 1024Byte 1MB = 1024 KB 1GB = 1024MB
(6)地址总线的宽度决定了CPU的寻址能力;数据总线的宽度决定了CPU与其他器件进行数据传送时的一次数据传送量;控制总线的宽度决定了CPU对系统中其他器件的控制能力。

(7)8086PC的内存地址空间分配的基本情况

(8)dword:双字型 32位 ffff ffff
   word:字型 16位 ffff
   字节型 8 位ff
   ax 字型 16位 ffff
   ah 字节型 8位ff
   db 字节型数据 ff
   dw 字形数据 ffff
   dd 双字型数据 ffff ffff

寄存器

寄存器知识小结

  1. 在进行数据传送或运算是,要注意指令的两个操作对象的位数应当是一致的。

  2. CPU通过地址总线访问存储器,8086CPU有20位地址总线,因此需要两个16位地址来形成20位的物理地址。

  3. 地址加法器采用物理地址=段地址x16+偏移地址的方法来合成物理地址的。

  4. 关于段地址为什么要左移4位(x16):因为段地址本身和偏移地址都是16位的,而8086有20位的地址总线,因此段地址偏移四位之后,变为20位数。

  5. 物理地址=段地址x16+偏移地址的本质含义是:CPU在访问内存时,用一个基础地址(段地址x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。

  6. 8086机中,任意时刻,CPU将CS:IP (Code Segment: Instruction Pointer)指向的内容当做指令执行。其中,CS为代码段寄存器,IP为指令指针寄存器。

  7. DS(Data Segmet)寄存器 是段寄存器,通常用来存放要访问数据的段地址。

  8. “[···]”表示一个内存单元。方括号中表示内存单元的偏移地址。比如读取10000H中的内容,可以使用以下程序段:
    mov bx,1000H
    mov ds,
    bx mov al,[0]

  9. 字在内存中存储时,要用两个地址连续的内存单元来存放,字的低位字节存放在低地址单元中,高位字节存放在高地址单元中。

  10. 任意时刻,SS:SP指向栈顶元素。SS(Stack Segment)为栈 段寄存器,SP(Stack Point) 为栈指针寄存器

  11. 一个栈段的容量最大为64KB,0000~ffff。2^10 ∙ 2^6 = 64KB

  12. CPU将内存中的某段内容当做代码,是因为CS:IP指向了那里;CPU将某段内存当做栈,是因为SS:SP指向了那里。

  13. si和di是和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用

  14. [ idata ] 用一个常量来表示地址, 可用于直接定位一个内存单元 ;
    [ bx ]用一个变量来表示内存地址, 可用于间接定位一个内存单元;
    [ bx+idata ] 用一个变量和常量表示地址, 可在一个起始地址的基础上用变量间接定位一个内存单元 ;
    [ bx + si ] 用 两 个 变 量 表 示 地 址 ;
    [ bx + si + idata ] 用两个变量和一 个常量表示地址。

  15. reg:ax,bx,cx,dx,sp,bp,si,di sreg:ds,ss,cs,es

  16. [….]寻址方式只有4个寄存器支持,分别是bx,si,di,bp。这四个寄存器只能单独出现或以4个组合出现:bx和si,bx和di,bp和si,bp和di。

  17. 只要在[ …. ]中使用寄存器bp,而指令中没有显性地给出段地址,段地址就默认在ss中。

  18. 在没有寄存器名存在的情况下,用操作符X ptr 指明内存单元的长度,X在汇编指令中可以为word或byte

标志寄存器
标志位 名称及全称 =1 =0
CF 无符号/进位借位标志/Carry Flag CY/Carry/进位 NC/No Carry/无进位
PF 奇偶标志/Parity Flag PE/Parity Even/1的个数/偶 PO/Parity Odd/奇
AF 辅助进位标志/Auxiliary Carry Flag AC/Auxiliary Carry/进位 NA/No Auxiliary Carry/无进位
ZF 零标志/Zero Flag ZR/Zero/运算结果/等于零 NZ/Not Zero/不等于零
SF 符号标志/Sign Flag NG/Negative/负 PL/Positive/非负
TF 跟踪标志/Trace Flag
IF 中断标志/Interrupt Flag EI/Enable Interrupt/允许 DI/Disable Interrupt/禁止
DF 方向标志/Direction Flag DN/Down/减少 UP/增加
OF 有符号/溢出标志/Overflow Flag OV/Overflow/溢出 NV/Not Overflow/未溢出

DEBUG命令

用DEBUG program.exe来用汇编调试一个程序
DEBUG默认所有的数据都用十六进制表示。

  1. r 查看CPU寄存器中的内容
    r ax 修改寄存器ax中的值
  2. d 段地址:偏移地址 查看该内存处的内容
    d 段地址:偏移地址 结尾偏移地址 查看该内存范围的内容
    使用d 段地址:偏移地址之后,接着使用d命令,可列出后续的内容
  3. e 改写内存中的内容
    “e 起始地址 数据 数据 数据 …”的格式
  4. t 命令,让CPU执行当前CS:IP指向的汇编命令
    用U命令查看内存中机器码的含义,用T命令执行内存中的机器码
  5. a 段地址:偏移地址 以汇编指令的形式在内存中写入机器指令的
  6. 注意:Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
  7. g 命令 “g 0012”将使Debug从当前CS:IP指向的指令执行,一直到(IP)=0012h位置。
DEBUG常用命令

-r ds
:1000
-d ds:10 18 ;查看1000:10~1000:18中的内容
-d cs:0 ;查看当前代码段中的指令代码
-d ss:0 ;查看当前栈段中的内容
-u cs:0 ; 以汇编指令的形式,显示当前代码段中的代码,0代码的
偏移地址
-r ds
:1000
-a ds:0 ;以汇编指令的形式,向从1000:0开始的内存单元中写入指

指令和操作符

指令

  • mov:传送指令

  • add:加法指令

  • push ax表示将寄存器ax中的数据送入栈,只能执行字操作。

  • pop ax表示就从栈顶取出数据送入ax
    将ax清零,可以用sub ax,ax;也可以用mov ax,0;sub ax,ax的机器码为2个字节,mov ax,0的机器码为三个字节。

  • inc bx 该指令表示对操作数加1(常量)即bx中的内容加1

  • dec bx 该指令表示对操作数减1(常量)即bx中的内容减1

  • and指令:逻辑与指令,按位进行与运算。

  • or指令:逻辑或指令,按位进行或运算。

  • div指令:除法指令
      被除数÷除数=商…余数
    (1)除数:8位或16位,在寄存器或内存单元中
    (2)被除数:默认放在AX或DX和AX中。
        AX:被除数(16位)÷ 除数(8位)= AL商 + AH余数
        DX,AX:被除数(32位d)÷ 除数(16位)= AX商 + DX余数
        其中DX存高位,AX存低位。
        div reg或div 内存单元

  • mul指令:乘法指令
      乘数*乘数=积
      乘数要么都是8位,要么都是16位,寄存器或内存单元中。d
      8位: AL * 8位reg或内存 = AX
      16位:AX * 16位reg或内存= DX AX
      其中,DX存高位,AX存低位、

没有寄存器名的情况下,word ptr 指明字单元,byte ptr 指明字节单元

  • loop指令:循环指令。CPU执行loop指令的时候,要进行两步操作①(cx)=(cx)-1; ②判断cx中的值,不为零则转至标号出执行程序,如果为零则向下执行。
        mov cx,循环次数
      s:  循环执行的程序段
        loop s

  • jmp指令:无条件转移指令
    jmp 段地址:偏移地址 = 用指令中给出的段地址修改CS,偏移地址修改IP
    若仅想修改IP的内容,可用“jmp 合法寄存器”的指令完成;
    jmp ax,在含义上好似:mov IP,ax
    jmp是无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
    “jmp short 标号”(转到标号处执行指令),这是段内短转移,它对IP的修改范围是-128~127,在汇编中对应的机器码是EBFF,FF为偏移地址,用的是补码表示。
    “jmp short 标号”的功能为:(IP)=(IP)+ 8位位移,段内近转移
    “jmp near ptr 标号”的功能为:(IP)=(IP)+ 16位位移,段内近转移
    “jmp far ptr 标号”为段间转移,又称远转移。
    “jmp word ptr 内存单元地址”段内转移
    “jmp dword ptr 内存单元地址”段间转移
      (CS)=(内存单元地址+2)
      (IP)=(内存单元地址)

  • jcxz有条件转移指令:所有有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址,修改范围是-128~127
      “jcxz 标号”等于if((cx)==0) jmp short 标号;

  • ret指令:近转移指令,进行下面两步操作
      (1) (IP)=((ss)* 16+(sp))
      (2) (sp)=(sp)+2
      相当于:
      pop IP

  • retf指令:远转移指令,进行下面4部操作
      (1) (IP)=((ss)* 16+(sp))
      (2) (sp)=(sp)+2
      (3) (CS)=((ss)* 16+(sp))
      (4) (sp)=(sp)+2
      相当于:
      pop IP
      pop CS

  • call指令:
    当前IP的转移位移
    call 标号 ;将当前的IP压栈后,转到标号处执行指令。进行如下操作
    (1) (sp)=(sp)-2
      ((ss)* 16+(sp))=(IP)
    (2) (IP)=(IP)+ 16 位位移。
    相当于
      push IP
      jmp near ptr 标号
    段间转移
      call far ptr 标号 ;进行如下操作
    (1)
      (sp)=(sp)-2
      ((ss)* 16+(sp))=(CS)
      (sp)=(sp)-2
      ((ss)* 16+(sp))=(IP)
    (2)
      (CS)= 标号所在段的段地址
      (IP)= 标号在段中的偏移地址
    相当于
      push CS
      push IP
      jmp far ptr 标号
    转移地址在寄存器中的call指令
    call 16位reg ;进行以下操作
      (sp)=(sp)-2
      ((ss)* 16+(sp))=(IP)
      (IP)=( 16 位reg)
    相当于
      push IP
      jmp 16 位reg
    转移地址在内存中的call指令
    call word ptr 内存单元地址
    相当于
      push IP
      jmp word ptr 内存单元地址
    call dword ptr 内存单元地址
    相当于
      push CS
      push IP
      jmp dword ptr 内存单元地址

  • adc指令:带进位加法指令,利用CF标志位上记录进位值
      指令格式:add 操作对象1,操作对象2
      功能:操作对象1 = 操作对象1 + 操作对象2 + CF
      比如指令adc ax,bx 实现的功能是:(ax)=(ax)+(bx) + CF

  • sbb指令:带借位减法指令,利用CF标志位记录借位值
    指令格式: sb b 操作对象1 ,操作对象2
    功能: 操作对象1 =操作对象1 - 操作对象2 - CF
    比如指令sbb ax ,bx 实现的功能是: (ax)=(ax)-(bx) - CF

  • cmp指令:比较指令
    cmp 指令格式: cmp 操作对象1, 操作对象2
    功能: 计算操作对象1 - 操作对象2 但并不保存结果, 仅仅根据计算结果对标志寄存器进行设置。
    比如, 指令cmp ax ,ax, 做(ax )一(ax )的运算, 结果为0, 但并不在ax 中保存, 仅影响flag 的相关各位。指令执行后: zf=l, pf=l, sf= 0, cf= 0, of= 0。

  • 常用的根据无符号数的比较结果进行转移的条件转移指令。
    字母表示意义如下。e: 表示equal; ne: 表示not equal; b: 表示below; nb: 表示not below; a: 表示above; na: 表示not above

指令 含义 检测的相关标志位
je 等于则转移 zf=1
jne 不等于则转移 zf=0
jb 低于则转移 cf=1
jnb 不低于则转移 cf=0
ja 高于则转移 cf=0且zf=0
na 不高于则转移 cf=1或zf=1
  • movesb指令:串传送指令,功能是将ds: si 指向的内存单元中的字节送入es:di 中, 然后根据标志寄存器df 位的值, 将si 和di 递增或递减。
  • movesw指令:串传送指令,功能是将ds: si 指向的内存字单元中的字送入es:di 中, 然后根据标志寄存器df 位的值, 将si 和di 递增2 或递减2。
  • rep指令:一般来说, movsb 和movsw 都和rep 配合使用, 格式如下:
    rep movsb
    作用是根据cx的值, 重复执行后面的串传送指令。
  • cld指令: 将标志寄存器的df位置0,正向
  • std指令: 将标志寄存器的df位置1,反向
  • sti指令:设置1F= l
  • cli指令:设置IF=O
  • pushfpopf指令:将标志寄存器的值压栈和出栈。
  • iret指令:通常和硬件自动完成的中断过程配合使用,它的功能用汇编语法描述为:
    pop IP
    pop CS
    popf
  • inout指令:分别用千从端口读取数据和往端口写入数据
  • shl命令:逻辑左移指令, 它的功能为:
      将一个寄存器或内存单元中的数据向左移位;
      将最后移出的一位写入CF 中;
      最低位用0补充。
      如果移动位数大千1 时, 必须将移动位数放在cl中。
      将X 逻辑左移一位, 相当于执行X=X*2。
    指令:
      mov al , 01001000b
      shl al, 1  ;将al 中的数据左移一位
    执行后(al)= I00I0000b, CF=0。
  • shr指令:逻辑右移指令, 它和shl所进行的操作刚好相反。

操作符

idata 表示常量
dup 用来进行数据重复的操作符
db 3 dup (0) ;定义3个字节,他们的都是0,相当于db 0,0,0
db 字节型数据
dw 字形数据
dd 双字型数据
offset 取得标号的偏移地址;offset start表示取得start的偏移地址
nop 空指令,不执行操作,但占一个程序步骤。占一个byte,8位即ff。