关于汇编的精彩讲解
字体: 小 中 大 | 打印 发表于: 2008-9-21 11:05 作者: LCL6000 来源: proteus仿真社区
“ 哎哟,哥们儿,还捣鼓汇编呢?那东西没用,兄弟用VB"钓"一个API就够你忙活个十天半月的,还不一定搞出来。”此君之言倒也不虚,那吾等还有无必要研他一究呢?(废话,当然有啦!要不然你写这篇文章干嘛。)别急,别急,让我把这个中原委慢慢道来:一、所有电脑语言写出的程序运行时在内存中都以机器码方式存储,机器码可以被比较准确的翻译成汇编语言,故几乎所有跟踪、调试工具(包括WIN95/98下)都是以汇编示人的,如果阁下对CRACK颇感兴趣……;二、汇编直接与硬件打交道,如果你想搞通程序在执行时在电脑中的来龙去脉,也就是搞清电脑每个组成部分究竟在干什么、究竟怎么干?一个真正的硬件发烧友,不懂这些可不行。三、如今玩DOS的多是“高手”,如能像吾一样混入(我不是高手)“高手”内部,不仅可以从“高手”朋友那儿套些黑客级“机密”,还可以自诩“高手 ”尽情享受强烈的虚荣感~~~~~~~~~~“醒醒!”
对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时CRACK出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ……)。但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用WINZIP、WINRAR…依次压迫,嘿嘿!)教程。大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么――这个接下来呢?―― Here we go!
编写汇编语言有两种主要的方法:1.使用MASM或TASM等编译器;2.使用除错程序DEBUG.COM。DEBUG其实并不能算是一个编译器,它的主要用途在于除错,即修正汇编程序中的错误。不过,也可以用来写短的汇编程序,尤其对初学者而言,DEBUG 更是最佳的入门工具。因为DEBUG操作容易:只要键入DEBUG回车,A回车即可进行汇编,过程简单,而使用编译器时,必须用到文本编辑器、编译器本身、LINK以及EXE2BIN等程序,其中每一个程序都必须用到一系列相当复杂的命令才能工作,而且用编译器处理源程序,必须加入许多与指令语句无关的指示性语句,以供编译器识别,使用 DEBUG 可以避免一开始就碰到许多难以理解的程序行。DEBUG 除了能够汇编程序之外,还可用来检查和修改内存位置、载入储存和执行程序、以及检查和修改寄存器,换句话说,DEBUG是为了让我们接触硬件而设计的。
在学汇编时,很多初学者对PC的寻址方式和很不理解,甚至是很难理解。的确,这方面的知识是很抽象的,需要比较强的空间想象能力。尤其是我们在输入字符串时,那这些字符是如何进行排列的呢?对于,这个问题,我相信很多初学者也是很难想象是如何排列。但是,我可以这样比喻:内存就是有很多栋“楼房”,“楼房”又是由“单元号”,“门户号” 组成,那“楼房”就相当于内存地址的段地址,“单元号”就相当于内存的的偏移地址,“门户号(家)”就相当于“变地址”,而每个单元有16个"门户号(家)",又当我们找到"门户号(家)"后,走进这个"门户号(家)"就会见到里面会有"人",而我们所说的人就是寄存器所指的"内容"了,我画个图给你们看就会一目了然了。
用DEBUG的D命令得出这样的效果:
|---------->0B1F就是"楼房"------>段地址
|
| |------>右边的就是"单元号"--->偏移地址
| |
| | |-------->这部分就是"门户号"----->变地址
| | |<------------------------------------------>|
0B1F:0100 00 80 FF 02 75 05 C6 46-00 00 C3 E8 8C EB B4 3B
0B1F:0110 CD 21 72 39 8B FA 33 C0-8B C8 49 26 34 00 0E 0B
'
'
'
[省略]
看完这个图之后,是不是就很明了呢?但是聪明的人就会有疑问,那我们怎么走进"门户号(家)"呢?问得好,所以了为了可以走进"门户号(家)",就出现了一个叫做"寻址方式"的概念!说白了,就是教你如何找到这个"门户号(家)".呵呵!
好现在都明白了吗?那你们就看看我是怎么理解PC的寻址方式(通俗易懂):
在这我就只介绍比较难理解的:
1:寄存器直接寻址:
你就想成:其实你已经站在你要找的"门户号(家)"面前了,直接敲门进去就OK了!
例子: MOV AX,[2000H]
MOV AX,2000H -->2000H为存放操作数单元号的符号地址
上面两者是不等效的
2:寄存器间接寻址方式:
你就想成:你已经站在你要找的"门户号(家)"的"单元号",你要找到它,必须知道它在当前"单元号"几楼.假如它在6楼,那你就上到6楼就OK了!!注意,最高只有16楼,因为什么呢?那就用DEBUG的D命令看看呀,慢慢数哦,呵呵!!
例子: MOV AX,[BX]
计算公式: 物理地址=16d*(DS)+(BX)
物理地址=16d*(DS)+(SI)
物理地址=16d*(DS)+(DI)
物理地址=16d*(SS)+(BP)
3:寄存器相对寻址方式:
你就想成:你要找的"门户号(家)"其实就在你家的楼上或者楼下,你要找到它,就 必须知道它在你楼上几楼,或者在楼下几楼!就OK了!
例子: MOV AX,COUNT[SI]
MOV AX,[COUNT+SI]
其中 COUNT为位移量的符号地址
计算公式: 物理地址=16d*(DS)+(BX)+8位位移量
或+(SI) 或 16位位偏移量
或+(DI)
物理地址=16d*(SS)+(BP)+8位偏移量
4:基址变址寻址方式:
你就想成:你要找的"门户号(家)"是跟住在同一栋楼的不同"单元号",你要找到它,就必须知道它是该栋的哪个"单元号",并且住在几楼!那样你就可以找到它了 !
例子: MOV AX,[BX][DI]
MOV AX,[BX+DI]
计算公式: 物理地址=16d*(DS)+(BX)+(SI)
或+(DI)
物理地址=16d*(SS)+(BP)+(SI)
或+(DI)
5:相对基址变址寻址方式:
你就想成:你就想成:你要找的"门户号(家)"是跟住在同一栋楼的不同"单元号",它比你高几层楼或者低几层楼,然后用的你目前的楼数+/-就可以得出你要找的住在几楼了!
例子: MOV,AX,MASK[BX][SI]
MOV,AX,MASK[BX+SI]
MOV,AX,[MASK+BX+SI]
以上三个例子是等效的!!
计算公式: 物理地址=16d*(DS)+(BX)+(SI)+8位位移量
或+(DI) 或 16位位偏移量
物理地址=16d*(SS)+(BP)+(SI)+8位位移量
或+(DI) 或 16位位偏移量
---------------------------------------------------------------------
呵呵,终于写完了这篇教程,好累哦!! 是不是觉得我的思维很另类呀,要创新呀!
书上太理论了,我就创新一个,不知道你们看得懂吗?
呵呵,反正你们不要!@##)(#$*!@(@我就行了,我很努力写了!!!
下面,我举个程序例子,让你们加深印象!!!
----------------------------------------------------------------------
编程步骤:
1: 建立缓冲区,为输入字符串(最多能输入9个)
2: 取缓冲区的首地址,以便后面进行"寄存器间接寻址方式"
3: 利用"寄存器间接寻址方式"取得实际输入字符个数,以便确认循环次数
4: 利用"寄存器间接寻址方式"输入字符串的最后一个字符
5: 利用LOOP指令和2号显示功能来进行倒着显示
----------------------------------------------------------------------
;程序功能:任意输入几个字符(最多能输入9个),按回车则倒着输出!
data segment
user_string db 10,0,10 dup(?)
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax

最新回复
jdimove (2008-9-22 21:17:29)
kous (2008-9-22 22:46:29)
<body>
<pre>
<h1>礦ision3 Build Log</h1>
<h2>Project:</h2>
D:\Program Files\keil\LIANXI\guangzhu.uv2
Project File Date: 09/15/2008
<h2>Output:</h2>
Build target 'Target 1'
assembling STARTUP.A51...
linking...
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=15
"guangzhu" - 0 Error(s), 2 Warning(s).
Build target 'Target 1'
assembling STARTUP.A51...
assembling GUANGZHU.ASM...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0000H
TO: 0002H
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=108
creating hex file from "guangzhu"...
"guangzhu" - 0 Error(s), 3 Warning(s).
Build target 'Target 1'
assembling STARTUP.A51...
assembling GUANGZHU.ASM...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0000H
TO: 0002H
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=108
creating hex file from "guangzhu"...
"guangzhu" - 0 Error(s), 3 Warning(s).
Build target 'Target 1'
assembling GUANGZHU.ASM...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0000H
TO: 0002H
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=108
creating hex file from "guangzhu"...
"guangzhu" - 0 Error(s), 3 Warning(s).
Build target 'Target 1'
assembling GUANGZHU.ASM...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0000H
TO: 0002H
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=108
creating hex file from "guangzhu"...
"guangzhu" - 0 Error(s), 3 Warning(s).
Build target 'Target 1'
assembling GUANGZHU.ASM...
linking...
*** WARNING L5: CODE SPACE MEMORY OVERLAP
FROM: 0000H
TO: 0002H
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: STARTUP.obj (?C_STARTUP)
ADDRESS: 080AH
Program Size: data=9.0 xdata=0 code=108
creating hex file from "guangzhu"...
"guangzhu" - 0 Error(s), 3 Warning(s).
</pre>
</body>
</html>
yueyujie (2008-9-24 13:58:27)