小弟初学汇编 请各位大大帮忙看一下这个例子,感谢!

SimonYeung 2008-11-20 12:03:55
程序如下:

A SEGMENT
NUM DB 00111001B
BUF DB 0AH,0DH,'(NUM)='
BUF0 DB 4 DUP(?)
A ENDS
B SEGMENT STACK
DB 200 DUP(0)
B ENDS
C SEGMENT
ASSUME DS:A,SS:B,CS:C
BEGIN: MOV AX,A
MOV DS,AX
LEA DI,BUF0
MOV AL,NUM
MOV CL,4
SHR AL,CL
OR AL,30H
MOV [DI],AL
OR AL,30H
MOV [DI],AL
INC DI
MOV AL,NUM
AND AL,0FH
OR AL,30H
MOV [DI],AL
INC DI
MOV BYTE PTR [DI],'H'
INC DI
MOV BYTE PTR [DI],'$'
LEA DX,BUF
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
C ENDS
END BEGIN



请问这里 MOV [DI],AL MOV BYTE PTR [DI],'H'这两条语句实现的是什么功能,MOV [DI],AL 这条语句能否理解为寄存器间接寻址,程序的输出结果是什么?

P.S. 问题比较多,主要是想请各位大大把这个程序以初学者能听懂的方式逐条解释一下,小弟十分感谢!~
...全文
144 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
SimonYeung 2008-11-20
  • 打赏
  • 举报
回复
上面是我自己的理解,如果有不对的地方,还请大家指正,感谢!~
SimonYeung 2008-11-20
  • 打赏
  • 举报
回复
经过今天下午的努力,终于是把这个程序给弄懂了,现在我自己来总结一下,希望对和我一样初学汇编的朋友们有所帮助:
原程序如下:

A SEGMENT
NUM DB 00111001B
BUF DB 0AH,0DH,'(NUM)='
BUF0 DB 4 DUP(?)
A ENDS
B SEGMENT STACK
DB 200 DUP(0)
B ENDS
C SEGMENT
ASSUME DS:A,SS:B,CS:C
BEGIN: MOV AX,A
MOV DS,AX
LEA DI,BUF0
MOV AL,NUM
MOV CL,4
SHR AL,CL
OR AL,30H
MOV [DI],AL
OR AL,30H
MOV [DI],AL
INC DI
MOV AL,NUM
AND AL,0FH
OR AL,30H
MOV [DI],AL
INC DI
MOV BYTE PTR [DI],'H'
INC DI
MOV BYTE PTR [DI],'$'
LEA DX,BUF
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
C ENDS
END BEGIN

由伪指令语句ASSUME DS:A,SS:B,CS:C可知A代表数据段,B代表堆栈段,C代表代码段。
数据段
A SEGMENT
NUM DB 00111001B
BUF DB 0AH,0DH,'(NUM)='
BUF0 DB 4 DUP(?)
A ENDS

定义了 8个 字节类型的变量:NUM为00111001,BUF为0A,BUF+1为0D,BUF+2为"(NUM)=”,BUF0到BUF+3为 4个内容为任意取值的字节变量。

代码段,前行语句MOV AX,A和MOV DS,AX完成 数据段A的段首址放到寄存器DS中,LEA DI,BUF0语句是将BUF0的偏移地址放到16位的DI目的变址寄存器中,此时可知DI的内容为0009,MOV AL,NUM将NUM变量的值00111001放到AL 8位寄存器中,此时AL的内容为39,同样MOV CL,4将4放到CL中,此时CL为04,SHR AL,CL是进行逻辑右移,即将AL中的内容39(二进制为00111001)向右移动4位,高位补零,移动后AL中的内容为03(二进制为00000011),CF进位标志位置1,OR AL,30H是对AL中内容进行逻辑加,结果为33,MOV [DI],AL将33放到DI存储的值的地址中,DI现在是0009,即将33放到以DS为数据段,偏移地址为9的存储空间中,即BUF0的值为33,INC DI将DI的内容+1,DI变为000A,MOV AL,NUM将00111001放到AL中,此时AL为39,AND AL,0FH功能是将AL的高4位置0,低4位保持不变,此时AL为00001001,即AL为09,OR AL,30H和前面一样,进行逻辑加,此时AL为39,MOV [DI],AL将39放到DI存储的值的地址中,DI现在是000A,即将39放到以DS为数据段,偏移地址为A的存储空间中,即BUF0+1的值为39,,INC DI将DI的内容+1,DI变为000B,MOV BYTE PTR [DI],'H'将H的16进制ASCii码48强制转换为字节后放到000B的偏移地址中,INC DI后DI的值为C,MOV BYTE PTR [DI],'$'同理,$的16进制ASCii码为24,000C的偏移地址的内容为24,LEA DX,BUF
MOV AH,9
INT 21H
,是执行DOS系统功能9号调用,功能为:将当前数据区中DS:DX所指向的以‘$’结尾的字符串送显示器显示,即将BUF到BUF+3的数据显示到屏幕上(因为BUF+3的值为$,所以显示到$停止),由于0AH和0DH分别表示换行和回车,所以程序执行以后会 换行然后回车,即此时"打印头"空1行以后转到第2行的开头,然后显示(NUM)=39H。完成。

P.S. MOV [DI],AL是寄存器间接寻址,此时PA=DS*16+EA,MOV BYTE PTR [DI],'H'由于字符H没有定义所以要给定H类型定义,如果该语句省去BYTE PTR ,那么编译器会报错,由于DI此时的值为地址的空间的类型是字节类型,所以要强制转换为BYTE类型。

最后感谢帮助我解决问题的热心朋友们,小弟初学汇编,以后有了问题还请各位大大多多帮忙,谢谢!~
cnzdgs 2008-11-20
  • 打赏
  • 举报
回复
'H'是字符,其值是字母H对应的ASCII码。
SimonYeung 2008-11-20
  • 打赏
  • 举报
回复
这里为什么要转换呢?
请问这里MOV BYTE PTR [DI],'H'中的‘H’是什么类型的?我同学说,'H'没有类型,这是怎么回事。
afangsky 2008-11-20
  • 打赏
  • 举报
回复
MOV BYTE PTR [DI],'H'为了把上放入buf0中di是十六位的要强制专换为byte八位的。
MOV [DI],AL 通过寄存器间接寻指把al存入bufo中
SimonYeung 2008-11-20
  • 打赏
  • 举报
回复
MOV BYTE PTR [DI],'H'这里为什么要强制转换为字节类型?
cnzdgs 2008-11-20
  • 打赏
  • 举报
回复
MOV [DI],AL是把转换好的ASCII码储存到BUF0里面,MOV BYTE PTR [DI],'H'是在数字后面加上H(16进制),MOV [DI],AL就是寄存器间接寻址,最后结果自己运行程序来看。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧