汇编--80x86指令系统

一、数据传送指令

 

1、通用数据传送指令

mov DST,SRC   

push

pop

xchg   交换

注意:段寄存器不能直接用Mov  传送,要先给通用寄存器,后给段寄存器  mov  ds, xxx   但是不可以给段寄存器CS赋值  mov cs,**  错误

mov AL ‘E’        ;把立即数(字符E的ASCII码送到AL寄存器中)
mov BX OFFSET TABLE    ;把TABLE的偏移地址(不是内容送到BX寄存器中),其中OFFSET为属性操作符。
mov AX Y[BI][SI]      ;把(BI)+(SI)+ 位移量Y 的存储单元的内容送到AX寄存器中

2、push  SRC  

3、pop   DST

push  pop  在16位指令中,必须是字的方式存取

8086  push,pop 不能用立即数寻址方式,切pop不允许使用CS寄存器。

286及其后继允许立即数进栈

push  pop不影响标志位

PUSHA(16)      所有寄存器进栈    AX,BX,CX,DX  指令执行前的  SP,BP,SI,DI    SP=SP-16

PUSHAD(32)     所有寄存器进栈    EAX,EBX,ECX,EDX  指令执行前的  ESP,EBP,ESI,EDI    SP=SP-32

POPA

POPAD

XCHG 交换指令

XCHG指令不允许的情况有以下四种:   
1. 不能同时都为内存操作数
2. 任何一个操作数都不能为段寄存器 重要 凡是S结尾的都不行
3. 任何一个操作数不能为立即数 凡是有立即数 都不对
4. 两个操作数的长度必须相等 长度必须相当
 
 

二、累加器专用传送指令

IN      输入

OUT  输出

XLAT  换码

2、用法:
(1)IN AX/AL, I/O端口地址          表示从外部设备输入数据给累加器

IN AX,80H
MOV DATA_WORD,AX   ;这两条指令把端口28H的内容经过AX传送到存储单元DATA_WORD中
mov DX,3FCH
IN EAX,DX

(2)OUT I/O端口地址,AX/AL         表示将累加器的数据输出给外部设备

OUT 5,AL  ;从AL中输出一个字节到5端口中

说明:当I/O端口地址不超过8位时,则直接放在指令中,若超过8位,则用DX间址。比如:

MOV DX,8080H
IN AL,DX

XLAT指令:     DS:【BX+AL】为地址 , 取出表中一个字节送到AL中

查表指令不影响标志位。

 

三、地址传送指令

LEA   有效地址传送器

LDS 指针送寄存器和DS

LES   指针送寄存器和ES 

LEA  REG,SRC 只是交换REG,SRC的值。没有处理段寄存器。下面的指令需要处理段寄存器

LEA BX,LIST
MOV BX,OFFSET LIST  ;这两条指令时相同的,使用第二条速度更快,但是这条指令不能和诸如 LIST[SI]或[SI]等复杂的操作数相连

LDS reg,mem     REG <-- mem             SREG  <-- SRC+2

四、标志寄存器传送指令

LAHF    标志入送AH  用于将标志寄存器的低八位送入AH,即将标志寄存器FLAGS中的SF、ZF、AF、PF、CF五个标志位分别传送到累加器AH的对应位(八位中有三位是无效的)

SAHF    AH送标志寄存器

PUSHF/PUSHFD    标志入栈

POPF/POPFD    标志出栈

 

五、类型转换指令

CBW                 (convert byte to word)

CWD/CWDE    (convert word to double)

CDQ              (convert double to quad)     双字转换为4字

BSWAP(byte swap)     字节交换

强制属性操作符PTR。数据类型 PTR 地址表达式

1.CBW

该指令的隐含操作数为AHAL。其功能是用AL的符号位去填充AH,即:当AL为正数,也就是最高位为0 ,则AH=0,否则,AH=0FFH。指令的执行不影响任何标志位。

2.CWD
该指令的隐含操作数为DXAX,其功能是用AX的符号位去填充DX,形成DX:AX双字,即如果(AX)的最高有效位为0,则(DX)为0,否则为0FFFFH。指令的执行不影响任何标志位。

CWDE ;80386+
该指令的隐含操作数为EAXAX,其功能是用AX的符号位填充EAX的高字位。指令的执行不影响任何标志位。

3.CDQ ;80386+
该指令的隐含操作数为EDXEAX,指令的功能是用EAX的符号位填充EDX。指令的执行不影响任何标志位。

 

BSWAP  R32      80486+   R32 指32位寄存器   
指令作用是:32位寄存器内的 字节(字节 两个单位)次序变反
(EAX)=9668 8368H
BSWAP EAX
-->(EAX)=6883 6896H

 

 

算数指令 
ADD
ADC     进位是CF啊,所以加上CF就是ADC了   带进位的加法   , 实现,(为实现双精度加法,必须用两条指令分别完成低位字和高位字的加法,而且用高位字的时候,可以考虑用ADC)
INC
XADD
opr是操作数,cnt是操作次数
 
CF  是否向更高位进位, CF可以用来表示无符号数的溢出
ZF
SF
OF  根据符号及其变化情况来设置,若两个操作数符号相同,而 结果的符号与之相反时,OF=1,否则OF=0. 仅对带符号数有效。
 
8位   无符号 0-255   带符号 -128 - +127     带符号的数在内存中是以补码的方式表示的,所以要-1 后取。 
16    无符号 0-65535    带符号 -32768 - +32767 
负数在计算机中 用补码表示
补码-->减一 成反码 -->原码

减法指令

SUB(subduction)  减法

SBB  带借位减法    -CF

DEC  自减1

NEG  求补   求反求反指令时NOT   加1

CMP  比较 和sub一样,但是并不保存结果,只是根据结果设置条件标志位。指令后往往跟一条条件转移指令,根据比较结果产生不同的程序分支。

减法中OF 设置方法:若两个数符号不同,且结果和减数符号相同,则OF=1.除这个情况,OF=0。OF=1说明带符号数的减法溢出。结果是错误的。0

neg是求补指令,举几个例子(以下数据均为16进制):
D8 求补之后是28 28+D8=100
14 求补之后是EC EC+14=100
1234求补之后是EDCC EDCC+1234=10000
1111求补之后是EEEF 1111+EEEF=10000
取反指令是not,也就是“非”指令,举几个例子:
只有当操作数为0时,求补运算的结果使CF=0,其他情况等于1.所以,只有当字节运算时对-128求补,以及字运算时对-32768求补和双字运算时对-2的31次求不情况下OF=1,其他时候=0
 
减去一个数。等于加上这个数在内存中按负数的表示方式。减数 求补  后在加就可以算减法了。
 
 

1:MUL SRC         无符号数的乘法

SRC是一个乘数,不能是立即数

  1. 当SRC为8位时  :AX<----AL*SRC
  2. 当SRC为16位时:DX:AX<-----AX*SRC                  ;DX存放高十六位
  3. 当SRC为32位时:EDX:EAX<------EDX*SRC           ;EDX存放高32位

2:IMUL SRC       有符号数乘法,与MUL SRC相同

MUL 如果高一半为0,则CF和OF都为0,否则为都为1          --这样可以检测相称的结果是字节还是字

IMUL 如果高一半世低一半的符号扩展,则CF和OF都为0,否则为1

 
 
 
 

 

除法指令DIV 

无符号除法IDIV 

整数除法

 被除数隐含的放在ax、dx:ax、edx:eax中
  • 与(AND)
  • 或(OR)
  • 非(NOT)    XOR也可以求某些位的反。只要把源操作的里技术字段的相应位置变成1就可以了。
  • 异或(XOR)    两位不同就取1,相同就取0
  • 测试(TEST)   和与一样,但是不保存结果,只设置状态位
NOT不影响标志位。其他4种指令将使CF位和OF位为0。AF无定义,而SF位、ZF位、PF位则根据结果设置
AND可以屏蔽某些位,也就是可以把这些位设置为0.
 
XOR AL , 3   0000 0011 
 XOR通常用来将寄存器清0,如 XOR AX,AX;
jcc指令是根据标志位工作的。jcc的具体行为在于它前面一条或者多条指令具体怎么影响标志位的。

   结果为0,则ZF=1。JZ指令是在ZF=1时跳转,ZF=0时不跳转。

表一:测试单个标志位的Jcc指令:

Jcc指令

描述

转移条件

JC,JB,JNAE

有进位时转移

CF=1

JNC,JNB,JAE

无进位时转移

CF=0

JZ,JE

为零(相等)时转移

ZF=1

JNZ,JNE

非零(不等)时转移

ZF=0

JS

为负时转移

SF=1

JNS

为正时转移

SF=0

JO

溢出时转移

OF=1

JON

不溢出时转移

OF=0

JP,JPE

‘1’的个数为偶数时转移

PF=1

JNP,JPO

‘1’的个数为奇数时转移

PF=0

表二:用于带符号数比较的Jcc指令(常用在CMP指令之后,以判断带符号数的大小)

Jcc指令

描述

转移条件

JG,JNLE

大于(不小于等于)时转移

SF=OF且ZF=0

JGE,JNL

大于等于(不小于)时转移

SF=OF

JL,LNGE

小于(不大于等于)时转移

SF<>OF

JLE,LNG

小于等于(不大于)时转移

SF<>OF或ZF=1

表三:用于无符号数比较的Jcc指令(常用在CNO指令之后,以判断无符号数的大小)

Jcc指令

描述

转移条件

JA,JNBE

大于(不小于等于)时转移

CF=0且ZF=0

JAE,JNB,JNC

大于等于(不小于)时转移

CF=0

JB,LNAE,JC

小于(不大于等于)时转移

CF=1

JBE,LNA

小于等于(不大于)时转移

ZF=1或CF=1

 

 

28、位测试指令

BT(位测试)

写法:BT REG16/MEM16,REG16/IMM8;或BT REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest不变。

BTS(位测试并置位)

写法:BTS REG16/MEM16,REG16/IMM8;或BTS REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位=1;

BTR(位测试并复位)

写法:BTR REG16/MEM16,REG16/IMM8;或BTR REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位=0;

BTC(位测试并复位)

写法:BTC REG16/MEM16,REG16/IMM8;或BTC REG32/MEM32,REG32/IMM8;

作用:CF=DEST的第index位,dest的第index位取反;

说明:若dest为寄存器,则以index除以16(dest为reg16)或32(dest为reg32)的余数作为测试位。当然,index最好不要超出操作数的位数。

若dest为内存操作数,则无论其类型为字或双字,测试位为相对于起始地址的位移,例如,设BX=50,X为字类型的变量,则执行指令BT X,BX;后,CF=X+6单元的第2位,因为50%8=6余2.

BTS、BTC、BTR指令可用于并发程序设计。

 

29、位扫描指令

BSF(前向位扫描)

写法:BSF reg16/reg32, reg16/reg32/mem16/mem32;(类型须匹配)

作用:dest=src中值为1的最低位编号(从低位向高位搜索)

BSR(后向位扫描)

写法:BSR reg16/reg32, reg16/reg32/mem16/mem32;(类型须匹配)

作用:dest=src中值为1的最高位编号(从高位向低位搜索)

说明:BSF和BSR搜索SRC操作数中首次出现1的位置,BSF从低位向高位搜索,BSR反之。若找到一个1,则置ZF=0,并存储位编号到DEST操作数中。若SRC=0,即没有1出现,则置ZF=1,且dest的值不确定。

比如,有如下二进制数0111 1111 1010 0100

执行bsf后,位编号为2,执行bsr后,位编号为14.

 

 

 4.移位指令 

(1)移位指令

指令格式:  SHL  OPR,CNT 

(1)将一个寄存器或内存单元中的数据向左移位

(2)将最后移出的一位写入CF中

(3)最低位用0补充

如果移动位数大于1时,必须将移动位数放在cl中。
1)SHL 逻辑左移指令 
2)SAL 算术左移指令 
3)SHR 逻辑右移指令 
4)SAR 算术右移指令 

(2)循环移位指令 

1)ROL 循环左移指令 
2)ROR 循环右移指令 
3)RCL 带进位循环左移指令 
4)RCR 带进位循环右移指令 
 
1)SHLD 双精度左移指令    SHLD  DST,REG,CNT
2)SHRD双精度右移指令
 
带进位的是把CF也连带上了。
每次最高位移入进位标志位CF
CF根据各指令规定设定,OF位只有当CNF=1时才是有效的,否则该位无定义。当CNT=1时,在移位时最高位发生变化,OF=1,否则为0.
算数移位指令适用于带符号数的运算,SAL乘以2 ,SAR除以2. 逻辑移位指令适用于不带符号数的运算。
 

串处理指令

MOVS(move string)  字节串传送

CMPS(compare string)  串比较指令

SCAS(scan string)  搜索指令

LODS(load from string)  读字符串指令

STOS(store in to string)  写字符串指令

INS(input from port to string)  串输入

OUTS(output string to port)  串输出

与上述指令配合使用的前缀:

REP(repeat)   重复串操作直到(CX)=0为止

REPE/REPZ(repeat while equal/zero)   相等/为0则重复

REPNE/REPNZ  不相等/不为0则重复

串处理指令处理存放在存储器里的数据串

 

转移指令比如 CMP AX,0 JNC EXIT EIXT:意思是CF=0,则跳转 ,表示的是AX大于或等于0的时候转移到EXIT处所以JNC也可以看成是加法没有进位,减法没有借位的时候转移

JB其实就是 JNAE: jump not above and equal 低于,即不高于且不等于则转移但执行这条语句之前先用CMP来比较2个无符号数,CMP比较无符号数后影响的是CF,所以JB应该是通过CF来判断的(注意:无符号数的比较在这里用高于和低于,有符号数的比较在这里用大于小于)

rep是字符串操作指令MOVS,CMPS等的前缀,在CX不等于0的情况下,对字符串执行重复操作.

 

BUF  DB 'hello world',0   ;定义被填充的缓冲区
MOV DI,BUF                ;将BUF的地址赋值给DI
MOV AL,0FFH               ;给AL寄存器赋值
MOV CX,11                 ;填充缓冲区长度
CLD                       ;清零方向标志,DI地址自增
REP STOSB                 ;开始填充

 


最终,BUF内存单元被FFH填充掉

CX中可以存放循环次数,

 

在保护模式,cpu通过段选择子找到段描述符表,来寻址。包括全局段表,局部段表,中断表。段选择子通过LGDR寄存器找到全局段表,通过IDTR找到中断表。lgdb即是设置全局表的地址和大小,lidt即是设置lidt的地址和大小

 

bsfl汇编指令:     
  intel汇编指令:bsf   oprd1,oprd2;     
  顺向位扫描(bit   scan   forward)     
  从右向左(从位0-->位15或位31)扫描字或双字操作数oprd2中第一个含"1"的位,并把扫描到的第一个含'1'的位的位号送操作数oprd1     
  AT&T格式汇编指令bsfl类似bsf,只是源操作数和目的操作数顺序相反。   

 

汇编语句bsfl %eax, %ebx, 把%eax的内容从0位开始扫描,找到第一个为1的赋给%ebx.
  btrl %eax, %ebx, 把%ebx中的%eax位复位。
  用C内嵌汇编实验了一下,确实如此。

 
 
 
 
 

 

你可能感兴趣的:(汇编--80x86指令系统)