做下面一道汇编题时碰到了一个问题,不明白,难道是书上错了
原题要求:内存中存着16个10位二进制整数,每个整数用两个字节来存放,其中低地址字节中存着该十位整数的9-2位,高地址字节中最高两位是该整数的1-0位,后面多余的位用0补齐,要求把转换后低地址字节中存放原整数的9-8位(在低二位,其余位用0补齐),高地址字节中存放原整数7-0位,且转换后的数仍按原序存放。
原题答案代码如下:
EXTRN LOAD:FAR,SAVE:FAR
N EQU 16
STAC SEGMENT STACK
DB 128 DUP(?)
STAC ENDS
DATA SEGMENT
SOURCE DW N DUP(?)
RESULT DB N*2 DUP(0)
NAME0 DB 'INPUT1.DAT',0
NAME1 DB 'OUTPUT1.DAT',0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STAC
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX
LEA DX,SOURCE ;数据区起始地址
LEA SI,NAME0 ;原始数据文件名
MOV CX,N*2 ;字节数
CALL LOAD ;从'INPUT1.DAT'中读取数据
;****BEGIN****
MOV DI,OFFSET RESULT
MOV BX,0
MOV CH,N
PRO: MOV AH,BYTE PTR SOURCE[BX]
MOV AL,BYTE PTR SOURCE[BX+1]
MOV DL,AH ;10位无符号二进制数高8位
MOV DH,AL ;10位无符号二进制数低2位
MOV CL,2
SHL AX,CL
SHL DX,CL
MOV AL,DH
MOV [DI],AL
MOV [DI+1],AH
ADD DI,2
ADD BX,2
DEC CH
JNZ PRO
;****END****
LEA DX,RESULT ;结果数据区首址
LEA SI,NAME1 ;结果文件名
MOV CX, N*2 ;结果字节数
CALL SAVE ;保存结果到文件
RET
START ENDP
CODE ENDS
END START
运行结果如图所示:
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323858][/img]
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323859][/img]
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323860][/img]
我想问原代码中的MOV AL,BYTE PTR SOURCE[BX]指令是改SOURCE[BX]这个数组元素的类型属性为BYTE,还是将整个SOURCE数组的类型属性改为BYTE?还有书上说PTR伪操作指令的作用范围只有当前指令,只是在当前指令赋予后面的表达式以指定类型属性或距离属性,而从下一条指令开始该表达式的类型或距离属性又和执行该指令前的属性一样,也就是说在当前指令之外该表达式仍保持原来的属性,单看运行结果而不看该指令原来的形式,上述指令功能好像改是SOURCE数组为字节数组,但书上说了,仅在这一句有效,而每次执行完计数自增2,所以后面SOURCE[BX+1]句也将SOURCE数组看成是字节数组,保证每次前一条指令都取原字数组的低字节,后一条指令都取原字数组的高字节。但从这个答案来看,问题似乎已经解决,但这时我又想到了先前自己的答案:把原MOV AL,BYTE PTR SOURCE[BX+1]句改成MOV AL,HIGH SOURCE[BX];再将ADD BX,2改为让BX计数每次自增1,我是这样看的,既然书上说PTR指令的作用范围只在当前句,SOURCE数组在这句以后自然还是字数组,而AL中要放字数组元素SOURCE[BX]的高字节,自然就是MOV AL,HIGH SOURCE[BX];但是因为BX是字数组元素序号,每次计数自增自然是1,但是运行结果却出人意料,每个元素转化后高字节中的数竟和低字节中的数一模一样,具体代码运行结果如下图所示:
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323863][/img]
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323868][/img]
[img=http://my.csdn.net/albert_williams/album/detail/1323869#1323869][/img]
不知究竟怎么回事?书上的话究竟有没有错?
[解决办法]
byte ptr 确实是只针对当前指令。
汇编里,对数组的操作,没有自增的功能和说法吧;如果是要将指针指向数组的下一个元素,需要自己给指针加上单个元素所占用的字节数。
mov al, HIGH SOURCE[bx] 这样的用法汇编里支持吗?好像没见过,编译应该通不过的吧,提示只能针对立即数操作。
[解决办法]
汇编链接时没有出错,说明所使用的汇编软件是支持这个伪操作符的。至于结果,对比下使用 HIGH 前后所生成的实际的 cpu 指令了。不能简单地停留在些语句的表面上,有时它的些规定和实际的功效可能和想像的有很大的差别。
至于图片,你给出的是相册中的地址,不是图片的 url 。你这图片的 url 应该是:/uploadfile/jiaocheng/20140182/2835/2014012818352631124.jpg
[解决办法]
那原代码中的MOV AL,BYTE PTR SOURCE[BX]指令是改SOURCE[BX]这个数组元素的类型属性为BYTE,还是将整个SOURCE数组的类型属性改为BYTE?
>> 这里其实是一样的吧。临时修改的应该是 SOURCE 的类型,SOURCE[BX] 是访问的其中的一个元素,但元素的类型是由 SOURCE 确定的;所以认为是修改的元素的类型还是数组的类型,意思上是一样的。况且,数组对汇编来说,并不是直接支持的,只是能够通过这样的方式形成类似的效果,至少汇编程序是不会直接通过元素序号来访问到指定的元素的,还得自己计算元素对应的数组内以字节为单位的偏移。
顺便问一下,怎么获取图片的URL呢?
>> 在图片上鼠标右键,菜单里选择最后的“属性”对话框里就可以看到了。
还有,从运算结果看,用MOV AL,HIGH SOURCE[BX]这句伪操作命令后程序在功能上究竟发生了什么样的变化?
>> 这个可以用调试或反汇编软件查看该行所对应的实际的指令吧。我这里的 ml6/Masm32 的汇编程序都不支持这样的用法,提示 HIGH/LOW 只能对立即数操作。