为什么要使用ROL指令?

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指令,它能实现什么功能。谢谢! :)

2
这是有点奇怪的代码。为什么不用 rol eax, 4 呢?而且为什么要保存和恢复 ebx(通常是被调用者保存的寄存器),即使它没有被使用? - gsg
@gsg 确实这两个操作都是无用的...你的观察很好。 - Aditya Bhatnagar
@gsg:我想知道它是否从一些原始的8086代码移植到386/32位寄存器。rol r16,imm8在186中是新的,因此在需要与8086兼容的代码中模拟rol AX,4时,就是你要使用rol ax,cl。顺便说一句,我在如何将二进制整数转换为十六进制字符串?的答案中确实使用了rol,通过立即4进行转换(还有SSE2和AVX512版本,可以并行转换所有半字节 :))。 - Peter Cordes
2个回答

15

该代码以十六进制形式打印出一个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进行AND操作实现的。

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


6

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


特别感谢您比较了shl/shr和rol指令 :) - Aditya Bhatnagar
不幸的是,这个函数选择破坏EAX的低字节,因此必须使用push/pop保存/恢复EAX。但是,如果您将旋转后的值复制到另一个寄存器以转换为数字字符,则8x rol eax,4非常方便和高效。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接