汇编4OPCODE
opcode原理
前缀域
切换操作数大小前缀 :
066h可以将32位的操作数切换成16位的操作数
B8 00010000 | MOV EAX,0x100
66:B8 0001 | MOV AX,0x100
8918 | MOV DWORD PTR DS:[EAX],EBX
66:8918 | MOV WORD PTR DS:[EAX],BX
切换地址大小(切换寻址模式) :
067h用于将32位存储器的寻址方式切换成16位的寻址方式(16位的存储器寻址方式中,只能使用
bx,si,di,bp寄存器作为内存地址) , 而32位汇编中,可以使用任意寄存器.
66:8918 | MOV WORD PTR DS:[EAX],BX
67:8918 | MOV DWORD PTR DS:[BX+SI],EBX
重复操作前缀:
0f2h,0f3h
F2:A4 | REPNE MOVSB
F3:A4 | REP MOVSB
F2:45 | INC EBP ; 没有起作用
修改默认段:
3E:8945 00| MOV DWORD PTR DS:[EBP],EAX;3E->ds
26:8918 | MOV DWORD PTR ES:[EAX],EBX;26->es
36:8918 | MOV DWORD PTR SS:[EAX],EBX;36->ss
2E:8918 | MOV DWORD PTR CS:[EAX],EBX;2E->cs
64:8918 | MOV DWORD PTR FS:[EAX],EBX;64->fs
65:8918 | MOV DWORD PTR GS:[EAX],EBX;65->gs
机器码翻译成反汇编的方法
83C404A178812801A35481280168548128018B0D7481280151684881280168448128016840812801FF15A4922801
查表(intel提供的1字节指令映射表)
将第一个字节取出, 取查表(例如
83h)

以高4位作为y轴,以低4位作为x轴, 坐标相交之处,就是这个code域对应的指令了, 如果查找的是
group,那么还需要进一步去查group表,(依然使用机器码去查)

接着需要用
83h的下一个字节(C4)作为modR/M域再进一步确认使用group中的哪一个. 将c4展开为二进制11000100
无论是直接在1字节对照表中,还是在
group表中, 得到的都是指令格式:ADD Ev,Ib格式解析:
ADD - 指令的助记符
Ev,Ib 说明指令有两个操作数
E - 第一个操作数是寄存器或内存操作数
v - 第一个操作数的大小和当前处理器模式一样(32位时,操作数大小就是32位的)
I - 第二个操作数是一个立即数, 说明在指令的
modR/M域后面还有一个Imm域, 保存着指令的立即数操作数(立即数域:04)b-立即数的大小是一个字节. 说明立即数域的长度是1字节
目前可以确认指令是:
Add Ev,04Ev中使用的寄存器的名字, 由modR/M域来提供. 需要去查询
modR/M表modR/M表的组成:
表的左列, 是寄存器或内存操作, 在表的顶列,是纯寄存器操作数.
当操作数的类型是
G的时候, 表示操作是纯寄存器. 应当到表的顶列去取出寄存器的名字.当操作数的类型是
E的时候, 表示操作数可能是寄存器,可能是存储器, 应当在表的左列取出操作数.无论在那列, 都有很多寄存器, 此时需要使用操作数的大小来选择一款寄存器.


当前求出的指令就是:
Add esp , 04;
ModR/M域保存着指令的比较复杂的寻址方式。它携带着一下信息
操作数名称(寄存器、内存地址)
是否存在SIB域
是否存在相对偏移
ModR/M域占一个字节,可以将这一个字节拆分成一下格式。
89 D8 move eax,eb
D8=11011000
Mod Reg R/M
11 011 000
SIB域主要保存那些寄存器寻址的操作数中,带有乘法运算的部分。
例如:mov eax,[ebx*4]
13字节汇编指令的赏析
LOCK MOV DWORD PTR ES:[EDX*4+ECX+0AA],11
F0:26:C7 87 91 AA000000 11000000
前缀 OPCODE MODR/M SIB DISPLACEMENT IMMEDIATE
F0:26 C7 84 91 AA000000 11000000
解析例子
;例子1
83C404
A178812801
A354812801
6854812801
8B0D74812801
51684881280168448128016840812801FF15A4922801
code域: A1
mov eax,Ov
O - 存储器直接寻址方式,
说明指令的下一个字节就是一个内存地址
v - 操作数的大小就是`dword ptr`
mov eax,dword ptr[0x01288178]
code域: A3
mov Ov,eax
mov dword ptr[0x1288154],eax
6854812801
code域: 68
push Iz
I - 立即数
z -
push 1288154
8B0D74812801
code域: 8B
Mov Gv,Ev
ModR/M域: 0D
Gv : 在表的顶部: ecx
Ev : 在表的左边: disp32 - 偏移域
偏移域 : 74812801=>0x01288174
mov ecx,[0x1288174]
; 例子2
C7048100100000
C784810010000000100000
898C8100100000
code: C7 => mov Ev,Iz
modR/M: 04
Ev => [--][--]
SIB : 81 左边找到的寄存器 + 顶上找到的寄存器
然后将找到寄存器作为存储器寻址方式写上
eax*4+ecx
mov [eax*4+ecx] ,01000h
code: C7 => mov Ev,Iz
modR/M: 84
Ev => [--][--]+disp32
SIB : 81 => eax*4+ecx
disp32 : 00100000 => 1000h
[--][--]+disp32 => [ eax*4+ecx+01000h]
Iz : 00100000
最终的指令: mov [eax*4+ecx+01000h],01000h
code : 89 => Mov Ev,Gv
modR/M: 8C =>
Ev => [--][--]+disp32
Gv => ecx
SIB : 81 => eax*4+ecx
disp32 => 00100000
最终的指令 :Mov [eax*4+ecx+01000h],ecx
; 例子3
E912563545
E865123314
FF2556781234
code:E9 => jmp Jz
J => 操作是一个偏移值(立即数)
z => 32位
最终的指令:
jmp eip+45355612+5(指令自身长度)
code : E8 => call jz
最终的指令:
call eip+14331265+5
code FF:
modR/M 25 -> 00100101 => jmp Ev
Ev => disp32
disp32 => 56781234 => 034127856h
最终的指令
jmp [034127856h]
汇编4OPCODE的更多相关文章
- u-boot源码汇编段简要分析
Hi,大家好!我是CrazyCatJack,你们可以叫我CCJ或者疯猫.今天我给大家带来的是u-boot的源代码汇编段分析,以后还会给大家讲解后续的C代码,请持续关注哦^_^ 先简单说一下u-boot ...
- GCC 预处理、编译、汇编、链接..
1简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objective ...
- GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...
- Beennan的内嵌汇编指导(译)Brennan's Guide to Inline Assembly
注:写在前面,这是一篇翻译文章,本人的英文水平很有限,但内嵌汇编是学习操作系统不可少的知识,本人也常去查看这方面的内容,本文是在做mit的jos实验中的一篇关于内嵌汇编的介绍.关于常用的内嵌汇编(AT ...
- 从linux0.11中起动部分代码看汇编调用c语言函数
上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...
- C内嵌汇编-格式
C内嵌汇编-格式: __asm__(汇编语句部分:输出部分:输入部分破坏描述部分);C内嵌汇编以关键字"__asm__"或"asm"开始, 下辖四个部分, 各部 ...
- 20145212——GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...
- C程序汇编运行模式简析
SJTUBEAR 原创作品转载请注明出处 /<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1. 汇编 ...
- 生成ARM汇编
使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLC ...
随机推荐
- WC2017游记
Day0 到杭州之后出了点锅换了辆车,等了好久才开= =到宿舍发现路由器就在房门口,稳啊,过了一会儿就连不上了= =而且只有门口那个连不上,可以连上楼下的= =之后干了啥也忘了…… Day1 上午直接 ...
- laravel的核心概念:服务提供者provider解析
我们知道laravel和核心就是一个IoC容器, 被称之为服务容器. 那么作为IoC容器, 就必须要有绑定对象生成器的工作. 在laravel中是服务提供者来项服务容器中绑定对象生成器的. 百牛信息 ...
- 任务34:Cookie-based认证实现
任务34:Cookie-based认证实现 用mvc来实现以下Cookie-Base的认证和授权的方式 新建一个web MVC的项目 在我的电脑的路径:D:\MyDemos\jesse Ctrl+鼠标 ...
- HDU 5884 Sort (二分+k叉哈夫曼树)
题意:n 个有序序列的归并排序.每次可以选择不超过 k 个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过T, 问 k最小是多少. 析:首先二分一下这个 k .然后在给定 k 的情况下, ...
- maven构建web项目,cannot be cast to javax.servlet.Servlet
今天开发web的时候,需要用到servlet-api,于是在pom.xml中添加依赖 <dependency> <groupId>javax.servlet</group ...
- spoj NSUBSTR - Substrings【SAM】
先求个SAM,然后再每个后缀的对应点上标记si[nw]=1,造好SAM之后用吧parent树建出来把si传上去,然后用si[u]更新f[max(u)],最后用j>i的[j]更新f[i] 因为每个 ...
- PAT团体程序设计天梯赛 - 模拟赛
由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz 总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~ L1-1 N个数求和 ...
- tyvj 1391 走廊泼水节【最小生成树】By cellur925
题目传送门 题意简化:给你一棵树,要求你加边使它成为完全图(任意两点间均有一边相连) ,满足原来的树是这个图的最小生成树.求加边的价值最小是多少. 考虑Kruskal的过程,我们每次找一条最短的,两边 ...
- Caffe实战三(依赖包解析及环境配置)
前面的文章使用的软件环境是开始时通过apt-get命令所安装的,本文将通过编译源码的方式重新配置一个可迁移的软件环境.(参考:<深度学习 21天实战Caffe> 第五天 Caffe依赖包解 ...
- Python 教程资源
1.廖雪峰的官方网站 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386 ...