打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
探索机器码(8086)
对于mov指令CPU手册的指令集如下
image.png
接下来我们来看看,指令的真正含义,了解指令在内存中的形式!(8086CPU)
可以看出 mov reg->reg 占2字节
其中89的含义可以查到 是 r/m16 <- r/m16
第二个字节是我们需要研究的地方
image.png
MOV AX,BX 11 011 -> 000 D8 AX<-BXMOV BX,AX 11 000 -> 011 C3 BX<-AXMOV AX,CX 11 001 -> 000 C8 AX<-CXMOV CX,AX 11 000 -> 001 C1 CX<-AXMOV AX,DX 11 010 -> 000 D0 AX<-DXMOV DX,AX 11 000 -> 010 C2 DX<-AX
这里可以看到一些规律 11 暂时不能确定
可以发现每3位代表一个寄存器
000 AX 011 BX 001 CX 010 DX
为啥不是A B C D从大到小? 寄存器是以使用频率来进行排序的 AX 累加器 BX 基址器 CX 计数器 DX 数据器 累加器使用频率看来是最高的
如果上述规律成立 那么我们应该可以直接写16进制来实现我们想要的操作
MOV BX,DX 11 010 011 89D3MOV AX,CX 11 001 000 89C8MOV CX,DX 11 010 001 89D1MOV DX,BX 11 011 010 89DA
image.png
结果与我们预想的相同
另外4个通用寄存器
image.png
MOV SI,AX 11 000 -> 110 D8 SI<-AXMOV DI,BX 11 011 -> 111 C3 DI<-BXMOV BP,CX 11 001 -> 101 C8 BP<-CXMOV SP,DX 11 010 -> 100 C1 SP<-DX
000 AX 011 BX 001 CX 010 DX
110 SI 111 DI 101 BP 100 SP
8个通用寄存器 正好用完3位 合情合理的设定
接下来 测试 11的作用 猜想其为寄存器之间交换数据的标志
image.png
MOV AX,BX 89D8 D8: 11 011 000MOV DS,AX 8ED8 E8: 11 101 000MOV AX,ES 8CC0 C0: 11 000 000MOV AX,[0100] A10001 //明显不一样嘛 位数都不同
可以发现寄存器之间交换数据 前两位都是11
8E reg -> sreg 8C sreg -> reg
段寄存器命令如果还是89 3位放不下 这里更换指令 也是正常的
image.png
DS 011 ES 000 SS 010 CS 001
那么我们来手写下面指令 mov ds,ax 8EC3 mov cx,es 8CC1 mov bx,cs 8CCB mov ss,dx 8ED2
image.png
可以发现8EC3 不是 mov ds,ax命令 因为 8E的时候 寄存器表示的位置与 89 8C的位置不一样!
mov ss,dx只是巧合 他们寄存器编号都是010
在8E下 寄存器的表示顺序 11(寄存器之间) 011(目标段寄存器) 001(源寄存器) 那么8ED9表示 mov ds,cx 而不是 mov cs,bx
image.png
.
下面总结一下各个寄存器的二进制表达
AX 000 BX 011 CX 001 DX 010
SI 110 DI 111 BP 101 SP 100
DS 011 ES 000 SS 010 CS 001
交换规律
通用寄存器之间 89 11(模式) xxx(源寄存器) => xxx(目标寄存器)
段寄存器 => 通用寄存器 8C 11(模式) xxx(源段寄存器) => xxx(目标通用寄存器)
通用寄存器 => 段寄存器 8E 11(模式 xxx(目标段寄存器) <= xxx(源通用寄存器)
直接寻址方式
image.png
可以看到 操作 AX寄存器的命令有些不同,从手册上也可以看到AX寄存器与地址交互的指令比其他寄存器短!
AX寄存器 格式 A1(模式) [地址]
验证其他寄存器的格式
image.png
可以看到 除了AX 其他通用寄存器直接寻址的命令是 8B
段寄存器直接寻址的命令是8E
十六进制 模式 寄存器 模式编号 模式 1E 00 011 110 bx 0E 00 001 110 cx 16 00 010 110 dx 36 00 110 110 si 3E 00 111 110 di 2E 00 101 110 bp 26 00 100 110 sp 1E 00 011 110 ds 06 00 000 110 es 16 00 010 110 ss 0E 00 001 110 cs
寄存器码和上面一直 段寄存器依然换指令来表示
猜想格式为 00(模式) xxx(寄存器) 110(模式) 头尾来确定是直接寻址模式 后面会继续验证
地址位数需要按小端的读法 00 01 -> 01 00
寄存器间接寻址方式
注意这种寻址方式 能当地址的寄存器只有 bx 基址寄存器 si 源址寄存器 di 目标地址寄存器 bp 栈底寄存器
image.png
看一下机器码
image.png
命令和直接寻址一样是 8B
十六进制 模式 寄存器 模式编号 模式 07 00 000 111 ax,[bx] 0F 00 001 111 cx,[bx] 17 00 010 111 dx,[bx] 0C 00 001 100 cx,[si] 1D 00 011 101 bx,[di] 4E 01 001 110 cx,[bp+00] bp 的寻址应该归入寄存器相对寻址方式
看起来好像应该是 111 [bx] 100 [si] 101 [di]这样的形式 验证一波
image.png
十六进制 模式 寄存器 模式编号 模式 07 00 000 111 [bx],ax 04 00 001 100 [si],ax 05 00 010 101 [di],ax
地址在前面时也满足这样的规律
那么猜测一下
00 表示 直接或间接寻址
xxx表示寄存器
110 表示直接寻址
111 表示用[bx]寻址
100 表示用[si]寻址
101 表示用[di]寻址
寄存器相对寻址方式
image.png
十六进制 模式 寄存器 模式编号 模式 47 01 000 111 ax,[bx] 44 01 000 100 ax,[si] 45 01 000 101 ax,[di] 46 01 000 110 ax,[bp]
image.png
十六进制 模式 寄存器 模式编号 模式 47 01 000 111 ax,[bx] 87 10 000 111 ax,[bx]
image.png
寄存器间接寻址方式命令依然是 8B
基本和间接寻址方式一样 多了1字节或2字节描述偏移的地址
1字节 前两位01 2字节 前两位 10
1字节时以补码的方式读取地址大小 ff = -1 81 = -7f
2字节时直接按小端方式读取地址!
基址变址寻址方式
image.png
image.png
十六进制 模式 寄存器 模式编号 模式 00 00 000 000 [bx + si] 01 00 000 001 [bx + di] 02 00 000 010 [bp + si] 03 00 000 100 [bp + di]
看来基址变址内寻址方式是寄存器通过累加得到地址的
相对基址变址寻址方式
image.png
十六进制 模式 寄存器 模式编号 模式 40 01 000 000 [bx + si] 81 10 000 001 [bx + di] 42 01 000 010 [bp + si] 83 10 000 011 [bp + di]
实际上就是 间接寻址和变址寻址的组合形式
对于 mov 指令 能够总结出以下规律
通用寄存器编号
AX 000 BX 011 CX 001 DX 010
SI 110 DI 111 BP 101 SP 100
段寄存器编号
DS 011 ES 000 SS 010 CS 001
寄存器地址编号
[bx] 111 [si] 100 [di] 101 [bp] 110
[bx + si] 000 [bx + di] 001 [bp + si] 010 [bp + di] 011
寄存器间交换规律
通用寄存器之间 89xx 11(模式) xxx(源寄存器) => xxx(目标寄存器)
段寄存器 => 通用寄存器 8Cxx 11(模式) xxx(源段寄存器) => xxx(目标通用寄存器)
通用寄存器 => 段寄存器 8Exx 11(模式) xxx(目标段寄存器) <= xxx(源通用寄存器)
直接或间接寻址
直接寻址 => AX寄存器 A1 cccc(偏移量) 对于直接寻址 ax寄存器有专门的指令
直接寻址 => 非AX通用寄存器 8Bxx 00(模式) xxx(寄存器编号) 110(直接寻址) 后面跟2字节偏移 以小端方式读取地址
直接寻址 => 段寄存器 8Exx 00(模式) xxx(寄存器编号) 110(直接寻址) 后面跟2字节偏移 以小端方式读取地址
寄存器间接寻址 => 通用寄存器 8Bxx 00(模式) xxx(寄存器编号) xxx(寄存器地址编号)
寄存器相对寻址 => 通用寄存器 8Bxx cc(偏移) or 8Bxx cccc(偏移) 01 or 10(01后面跟1个字节 10后面跟2个字节) xxx(寄存器编号) xxx(寄存器地址编号) 偏移为单字节时,以补码方式读取! 2字节以小端方式读取
基址变址寻址 => 通用寄存器 8Bxx 00(模式) xxx(寄存器编号) xxx(寄存器地址编号)
相对基址变址寻址方式 => 通用寄存器 8Bxx cc(偏移) or 8Bxx cccc(偏移) 01 or 10(01后面跟1个字节 10后面跟2个字节) xxx(寄存器编号) xxx(寄存器地址编号) 偏移为单字节时,以补码方式读取! 2字节以小端方式读取
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
80X86汇编语言程序设计教程(杨季文)习题答案二
深入系统底层
汇编(五)——数据传送指令一
原来汇编中的循环是这么玩儿的
汇编指令与机器码的相互转换--中原教程网
七种寻址方式(立即寻址、寄存器寻址)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服