8

我对汇编语言编程有点陌生,所以如果这个问题似乎无关紧要,请原谅我。我试图了解一个 32 位加法程序,以下是用于将加法结果(保存在 EAX 中)显示回控制台的过程之一:

;Procedure to display EAX as a 8 digit hex number

DISPH PROC NEAR

   PUSH EBX        ; Save EBX
   MOV CL,4        ; To rotate the register by 4 bits
   MOV SI,8        ; Count for displaying 8 digits

DISPH1:

   ROL EAX,CL      ; Rotate EAX left by 4 bits
   PUSH EAX        ; Save EAX
   AND AL,0FH
   ADD AL,30H
   CMP AL,'9'      ; if AL <= '9', AL contains the ASCII code
   JBE DISPH2       
   ADD AL,7        ; if AL > '9' , add 07H to AL to convert into ASCII

DISPH2:

   MOV AH,2H       ; O/P subprogram
   MOV DL,AL       ; Call MS-DOS O/P subprogram
   INT 21H         ; Display the data in DL register on screen
   POP EAX         ; retrieve EAX from Stack
   DEC SI
   JNZ DISPH1
   POP EBX         ; Restore EBX
   RET

DISPH ENDP

END             ; end of file

请帮助我理解为什么在 DISP1 标签下使用 ROL 指令,以及它实现了什么。提前致谢。:)

4

2 回答 2

14

该代码以十六进制打印一个 32 位值。ROL 指令在这里很方便,因为它可以让您以最高到最低的顺序处理半字节。

考虑值 0xCAFED00D。要打印前四个字母,您必须按此顺序提取值 'C' A' 'F' 和 'E'。

 EAX = 0xCAFED00D

 ROL EAX, 4   -> EAX = AFED00DC (lowest nibble is C)
 ROL EAX, 4   -> EAX = FED00DCA (lowest nibble is A)
 ROL EAX, 4   -> EAX = ED00DCAF (lowest nibble is F)
 ROL EAX, 4   -> EAX = D00DCAFE (lowest nibble is E)

 and so on..

如您所见,此序列将感兴趣的值移动到最低的半字节。通过将结果值与 0x0f 进行与运算来提取此值。

之后该值被转换为十六进制字符并通过 DOS BIOS 输出。

于 2013-11-08T11:14:59.153 回答
6

它用于在显示操作期间迭代数字的位数。在每次迭代中,它将与要显示的下一个数字对应的位设置到 EAX 的低字节中。与 SHL/SHR 操作不同,ROL 将在整个显示例程完成后保留 EAX 中的原始值。ROL从最高位开始显示自然方便(SHR通过32个处理位可以达到类似的效果,但ROL更直接)。

于 2013-11-08T11:13:54.470 回答