鱼C论坛

 找回密码
 立即注册
查看: 3019|回复: 7

[技术交流] 学习汇编的一个好方法[转载]

[复制链接]
发表于 2011-7-2 22:34:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在学汇编时,很多初学者对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
  lea dx,user_string ;建立输入字符串缓冲区
  mov ah,0ah
  int 21h
  xor si,si
  xor bx,bx
  mov bx,dx
  mov cx,[bx+si+1] ;看这个就是"寄存器间接寻址方式"
  xor ch,ch ;其目的就是取实际输入字符个数
  mov di,cx
  lop: mov ah,2
  mov dx,[bx+di+1];看这又是"寄存器间接寻址方式"
  int 21h ;其目的就是取输入字符串的最后一个字符
  dec di
  loop lop ;依次循环倒着输出字符
  mov ah,4ch
  int 21h
  code ends
  end start
本文转载自互联网  本人不做任何解释

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
loop + 1 + 1 赞一个!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-7-2 23:52:22 | 显示全部楼层
对于多个偏移结合数组还是很好理解的吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-7-3 09:58:34 | 显示全部楼层
还行呢楼主,不过对于逻辑地址和物理地址的理解,还算比较简单吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-7-3 12:36:06 | 显示全部楼层
学习了,好文章
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-10-16 22:53:58 | 显示全部楼层
我来看看,想学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-10-17 08:06:48 | 显示全部楼层
非常感谢啊!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-11-7 21:07:50 | 显示全部楼层
不看还能理解,越看越迷糊、、、
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-1 09:22:31 | 显示全部楼层
言简意赅,通俗易懂。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-18 08:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表