汇编网首页登录博客注册
masmaster的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
文章收藏

[2010-07-09 21:34] 笔记:【机器语言与汇编指令】

机器语言是CPU理解和使用的,用于控制它的操作的二进制代码。
8086到奔腾的机器语言指令长度从1字节到13字节不等。
8086-80286的指令时16位模式的指令。 这些16位指令与那些以16位指令模式编程操作的80386或以上的cpu是兼容的。但是后者可能带有前缀。 当机器按照实模式操作时,80386或以上cpu假定所有指令都是16位模式。
16位指令方式:
【1-2字节操作码】【0-1字节MOD|REG|R/M】【0-1字节偏移】【0-2字节立即数】

32位指令方式:
【0-1字节操作数前缀】【0-1字节寄存器前缀】【1-2字节操作码】【0-1字节MOD|REG|R/M】【0-1字节比例变址】【0-4字节偏移】【0-4字节立即数】

32位指令方式的头两字节叫做替换前缀, 因为它们不是必须出现的。第一个用来修饰指令操作数的大小第二个用来修饰寄存器大小。如果80386-奔腾按16位指令模式的机制操作(实模式或保护模式), 而且 用的是32位寄存器, 则指令的前面将出现寄存器前缀66H,如果CPU按32位指令模式操作并用32位寄存器, 则寄存器前缀缺省。如果16位寄存器出现在32位指令模式中,要用寄存器前缀选择16位寄存器@#¥#¥开始有点晕头晕脑的~~
16位指令模式用8位16位寄存器及寻址方式。而32位指令模式使用8位及32位寄存器及寻址方式。。
32位寄存器可以用于16位模式,16位模式也可用于32位模式。
如果应用8位及32位数据,就选择32位模式。 同样,如果使用8位及16位数据就选择16位模式。
通常, 模式的选择是OS的功能。

【1】操作码
操作码选择CPU执行的操作。多数机器语言之来那个的操作码长1到2个字节。如:
第一字节:          第二字节 
[][][][][][][D][W] [][]|[][][]|[][][];
____________________MOD|R E G |R/M____
第1字节的前六位是操作码。 后面的D表示数据流的方向,后面的W表示数据类型是字还是字节, 如果W=1则字/双字,W=0则表示字节。 D=1表示数据从位于指令第2字节的R/M想REG流动,如果操作码中的D=0,则表示数据从REG流向R/M。

【2】MOD域
MOD域规定了所选指令的寻址方式,MOD选择寻址类型以及所选的类型是否有偏移量。
16位指令模式确定的MOD域
-------------------------
模式    功能
00      没有偏移
01      8位符号扩展位移量
10      16位位移量  
11      R/M是寄存器
-------------------------
32位指令模式的MOD域大致与16位相同,唯模式10为32为位移量。
如果MOD的内容是11时, 他选择的是寄存器寻址方式。寄存器寻址用R/M域规定用寄存器儿不用内存单元的位置。,假如MOD的内容为00,01,10则R/M选择数据存储器寻址方式。
当cpu执行指令时,所有8位的偏移量带符号扩这成16位偏移量,类似于movzx和movsx,即零扩展和符号扩展。
如果指令为32位模式,MOD域说明了地址尺寸的替换前缀的选择,或者CPU的工作模式,当MOD域是10的时候,允许方位保护模式的4GB字长。,80386以及更高的cpu只有按32位指令模式操作时才允许8位或32位的位移量,除非出现地址替换前缀。假如选择了8位的偏移量,cpu扩展他的符号称为32位位移量。

【寄存器的分配】
下面表图列出了REG域与R/M域当MOD=11时的寄存器分配。
---------------------------------------
代码   W=0(字节)W=1(字) W=1(双字)
000    AL         AX        EAX
001    CL         CX        ECX
010    DL         DX        EDX
011    BL         BX        EBX
100    AH         SP        ESP
101    CH         BP        EBP
110    DH         SI        ESI
111    BH         DI        EDI
----------------------------------------

例子: 机器码8BEC对应的二进制码和汇编指令
第一字节  第二字节
100010  11   11   101  100
~~~~~~  ~~   ~~   ~~~  ~~~ 
操作码  DW   MOD  REG  R/M
第一字节前6位为操作码mov,
D1位为D=1,数据流方向R/M->REG
D0位为W-1,数据类型:字
第二字节前两位为MOD=11(表示寄存器到寄存器操作)
D5~D3为REG=101,通过查表为BP
D2~D0为R/M=100,由于mod=11,则此时R/M为寄存器
查表为SP
结论:机器码8BEC的二进制码为100101111101100,汇编指令为:MOV BP,SP

如果指令668BECH出现在以16位指令模式操作的80386或更高cpu中,则第一字节的66H是为16位指令模式选择32位寄存器操作数的替换前缀。则这条汇编指令:MOV EBP,ESP

【R/M存贮器寻址】
上述说的是当MOD=11时,即寄存器寻址方式的情况, 如果MOD的内容为00,01,10,时R/M则表示的是存贮器寻址方式。
16位R/M存贮器寻址方式
-----------------------------
代码    寻址方式
000     DS:[BX+SI]
001     DS:[BX+DI]
010     SS:[BP+SI]
011     SS:[BP+DI]
100     DS:[SI]
101     DS:[DI]
110     SS:[BP]#特殊寻址
111     DS:[BX]
-----------------------------
例子: 如果MOD=00,R/M=101,寻址方式[DI]
如果MOD=01/10,对于16位模式寻址方式是[DI+16/8位偏移量]。
分析指令:MOV DL,[DI]的机器码是8A15H
100010  1    0    00   010   101
操作码  D位  W位  MOD  REG   R/M
操作码=MOV,
D位=1,数据流从R/M到REG
W位=0,数据类型为字节
MOD域00,表示没有位移量
REG域010,对应寄存器DL
R/M域101,由于MOD=0,则R/M域对应的是内存单元DS:[DI]
如果指令变成MOV DL,[DI+1],MOD域则为01,表示8位偏移量,则指令为:
8A5501H,即:
10010 10 01 010 101 0001 0000
2字节的指令变成了3字节的指令。

【特殊寻址方式】
MOV [OFFSET],REG
MOV NUMBER,REG
类似这样的,内存数据通过位移量de寻址方式。
当指令只有位移量的时候,MOD总为00,而R/M总为110。表示的是指令用[BP]寻址,没有位移量。实际上机器语言不能用没有位移量的[BP]寻址方式。每当出现BP寻址方式时,汇编程序把[BP]汇编为[BP+0]。
指令分析:MOV [1000H],AL
100010 00 00 000 110 00000000 00010000

操作码MOV
DW=00,表示数据从寄存器到内存,字节形式
MOD=00,没有位移量
REG=000,为8位AL寄存器
后面两字节为位移量1000H

指令分析:MOV [BP],AL
10010 00 01 000 110 00000000
操作码MOV
DW=00,表示字节从REG到内存方向床送
MOD=01,因为R/M用的是特殊的[BP]特殊寻址
REG=000,表示8位寄存器AL
R/M=110,表示DS:[BP]
最后一字节为0H的位移量。

【32位寻址方式】
80386以及更高的CPU的32位寻址方式通过32位指令模式,或用带地址前缀的67H的16位指令模式运行机制获得。
32位寻址方式的R/M编码
-----------------------------
代码     功能
000      DS:[EAX]
001      DS:[ECX]
010      DS:[EDX]
011      DS:[EBX]
100      使用比例变址字节
101      SS:[ESP]*
110      DS:[ESI]
111      DS:[EDI]
-----------------------------
* 如果MOD=00,寻址方式使用的32位位移量而不是EBP寄存器。类似于16位特殊寻址。
当R/M=100时,指令中出现比例变址字节的附加字段。比例变址字节指明附加的比例变址寻址格式:
00   000   000
ss   变址  基址
ss=00=X1
ss=01=X2
ss=10=X4
ss=11=X8
指令MOV EAX,[EBX+4*ECX]的机器码是67668B048BH,这条指令出现了地址尺寸和寄存器尺寸两个替换前缀, 这表示80386按16位指令模式操作时的指令,如果处理器按32位,则不需要替换前缀,指令就是8B048BH。前缀的用法依赖cpu的操作模式。

【立即指令】
作为使用立即寻址的16位指令的例子,MOV WORD PTR [BX+1000H],1234H,这6个字节指令的两个字节放操作码,DW,MOD域,REG域,R/M域,中间两个字节存放的是位移量1000H最后两个字节存放的是立即数1234H。
11000111 10000111;操作码,DW,MOD,REG,R/M
00000000 00010000;位移量1000H
00110100 00010010;立即数1234H

【段MOV指令】
如果段寄存器的内容通过MOV,PUSH/POP传送,指定寄存器设置的REG域选择段寄存器
段寄存器选择位
-------------------
代码     段寄存器
000      ES
001      CS*
010      SS
011      DS
100      FS
101      GS
-------------------
*处理器不允许MOV CX,R/M以及POP CS。
例子:MOV BX,CS
10001100 11001011
操作码MOV(立即数)
MOD=R/M为寄存器
REG=CS
R/M=BX

这种MOV指令的操作码不同于以前的MOV指令。 段寄存器可以在16位寄存器和16位内存单元之间传送。为了把立即数装入段寄存器,要首先把数据装入另外的寄存器然后再传送至段寄存器。
先写到这儿。总的感觉给我,以前不明的东西, 现在有些眉目了~,每次debug的时候, 反汇编后很多机器码都不知道做什么意思的, 今天看了看书里的详解, 有种豁然的感觉。
评论次数(0)  |  浏览次数(708)  |  类型(汇编语言笔记) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码