- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
深入系统底层之教你用0101写程序
————取自互联网
准备你的行囊----建立环境为了让大家更为轻松,除非迫不得已,我们尽量使用系统上已经安装的工具,在这一章里,下面两个外部工具是必须的
nasm: 作为汇编环境,官方网站http://www.nasm.us/?UltraEdit:作为16进制文本编辑器?同时,读者应该稍微具备的汇编知识,不用太多,知道下面这些指令的意义和用法即可
MOV 数据传送指令?ADD 加法指令?PUSH,POP 堆栈指令?CMP 比较指令?LEA 取地址指令?XOR 异或指令?所有的转移指令:JMP,JZ,JE
如果你还想进一步了解机器码的规范,可以下载?/source/1103630,里面有Intel的文档,以及本文用到的操作码查询表
用0和1写程序
曾经有人发给我一张图片,说世界上最牛程序员的键盘,键盘上一共两个键,01,当时年少无知,崇拜到抓狂,今天就让我们当回顶尖高手,用01直接写程序
请打开一个十六进制编辑器比如UltraEdit
把下面的二进制代码化为16进制输入进去(主要无法直接输入二进制代码)
1011 1000 0000 0001 0000 0000 0000 0101 0000 0001 0000 0000
十六进制为B8 01 00 05 01 00
将文件保存为文件,恭喜你,你刚刚完成了一个伟大壮举,你成功的让CPU计算出了1+1等于几,如果你兴匆匆的运行它,什么结果都看不到,那是因为为了保证代码简单,还没有告诉CPU输出结果的缘故,你愿意的话,可以运行cmd,切换到保存的目录,通过执行debug ,来看看我们到底输入了什么
1011 1000 代表 MOV ax?0000 0001 0000 0000 代表1?0000 0101 代表 ADD ax?0000 0001 0000 0000 代表 0001h
全文加起来表示?MOV ax,01h?ADD ax,01h
可以看出,我们的代码对应了两条机器指令,每个指令分成两个部分,比如MOV ax,1的二进制代码,1011 1000 代表 MOV ax他指定了本条指令的操作,叫做指令操作码(Opcode),0000 0001 0000 0000 代表1,指定了操作的操作数,可以看出机器码是有自己固定的格式,只要掌握了这个格式,查询对应的操作码,应该就可以掌握机器语言了
当然,事情也有复杂的一面,同一条汇编指令其操作码可能根据寻址方式或寄存器或操作数的位数的变化发生变化,比如同样是MOV指令,MOV al,1 和MOV ax,1中Mov的操作码分别为B0(1011 0000)和B8(1011 1000),而MOV ax,[ES:100]操作码会变成26 A1(前面26是段超越前缀,现在不用仔细追究),Intel8086规定的MOV指令就有12种之多,而且操作码的长度还有可能不同,这些操作码都可以在表中对应的查到,不需要记忆,下面我们就来了解机器语言指令的格式
自己设计机器语言指令格式在阅读Intel公司的实现前,为了不让您陷入一堆的解释和说明中迷惘无助,我们先来热热身,做点有趣的事情---思考一下如果让你自己来设计机器语言指令的格式,那么你会做出怎样的设计,下面是我的设计思路
首先汇编代码和机器代码是对应的,所以让我们来看看一条典型x86汇编指令:
MOV ax,1
这条指令由三个部分组成:指令,目的操作数,源操作数
指令为Mov,目的操作数ax,源操作数1,
ADD bx,2
指令为Add,目的操作数bx,源操作数2
相对应的我们可以考虑把机器指令格式也分成三个部分:指令码,目的操作数,原操作数
由于寄存器的数目是有限的,我们可以列个寄存器机器码指令表,这样代码中的寄存器就可以被替换为如下的机器代码,比如
000?? AX?001 CX?010 DX?011 BX?100 SP?101 BP?110 SI?111 DI?
然后我们再列一个指令码表,比如
MOVADDAND.?.?.
则MOV ax,1就可以变成00000000ax是000)
但是这样简单清晰的三个部分会出现一些问题mov bx,0,和mov bx,ax就有可能混淆了,因为ax的代码是000,和立即数0相同
所以我们需要一个标志位来确定是那种操作数,操作数有下面5种可能
目的操作数和原操作数的大小就比较难了,因为操作数可能是
1)一个立即数 比如1
2)一个寄存器 ax,bx,cx,dx
3)一个内存地址 [StringLable]
4)一个由一个或多个寄存器组成的内存地址
[ebx],[ebx+esi],[es
文档评论(0)