我正在一门微处理器课程中,使用Freescale CodeWarrior中的汇编语言来编程68HCS12微控制器。本周我们的任务是反转一个字节,所以如果字节是00000001,则输出应为10000000,或00101011到11010100。我们必须使用汇编语言,并被告知可以使用旋转和移位(但不仅限于)来完成此任务。我真的不知道该从哪里开始。
我正在一门微处理器课程中,使用Freescale CodeWarrior中的汇编语言来编程68HCS12微控制器。本周我们的任务是反转一个字节,所以如果字节是00000001,则输出应为10000000,或00101011到11010100。我们必须使用汇编语言,并被告知可以使用旋转和移位(但不仅限于)来完成此任务。我真的不知道该从哪里开始。
将两个寄存器视为位堆栈。如果您一次从一个寄存器移动一个位,会发生什么?
mov al, 10101110
mov ecx, 8
mov ebx, 0
loop1:
sal al, 1;
rcr bl, 1;
现在您将“carry”中的内容添加到“bl”中
loop loop1
而这就是全部
这原本是一条评论,但我想算了!
为了节省空间,可以使用一个16字节的表格来存储每次四位(半字节)的值,以代替256字节的表格。然后算法如下:
revval=(revdigit[inval&0x0f]<<4)|
revdigit[inval>>4];
如果我是一位教授,我肯定会喜欢其中一个移位在索引内部,另一个移位在外部的两个部分。
我也不得不为大学编写这个位反转程序(针对8位)。这是我的做法:
MOV AL, 10001011B ;set the value to test
MOV CL, 7
MOV DH, 1
MOV DL, 0
loop1: PUSH AX
AND AL, DH
PUSH CX
MOV CL, DL
SHR AL, CL
POP CX
MOV BH, AL
SHL BH,CL
OR CH,BH
DEC CL
INC DL
SHL DH, 1
POP AX
CMP DL, 8
JE END
JMP LOOP1
END:
00000001
;第二次为 00000010
等等。当你用 AL 进行 AND 运算时,你会得到 0
或类似于 100
或 10000
的结果,你必须将其向右移动,以获得 0
或 1
。
然后,将其放入 BH,并将其移动到所需的位置,即对于字节 0
,位置为 7
;对于字节 1
,位置为 6
等等。然后,进行 OR 运算得出我们的最终结果,并进行必要的 INC 和 DEC 操作。不要忘记有条件的跳转,并为下一个循环弹出 AX :)
结果将存储在 CH 中。 mov cx, 8 ; we will reverse the 8 bits contained in one byte
loop: ; while loop
ror di ; rotate `di` (containing value of the first argument of callee function) to the Right in a non-destructive manner
adc ax, ax ; shift `ax` left and add the carry, the carry is equal to 1 if one bit was rotated from 0b1 to MSB from previous operation
dec cx ; Decrement cx
jnz short loop ; Jump if cx register Not equal to Zero else end loop and return ax
我使用 dec 指令而不是 sub,因为它只需要一个字节,而 sub 需要三个字节。此外,编译器似乎总是通过选择 dec 来进行优化。
编辑:还要注意的是,rcl ax
(3 字节)虽然等价于adc ax, 0
(2 字节)后跟shl ax
(2 字节),但效率更低。
请参见下面的评论,非常感谢 Peter Cordes 的见解。
rcl
指令,可以使用adc ax,ax
。两者在16位模式下都是2个字节,而且adc
指令在现代CPU上更快。你关于shl eax,1
和adc al,0
的解释是错误的:正确的应该是shl ax,1
和adc ax,0
,操作数大小与rcl
相同,在加入进位之前进行移位。此外,dec cl
是2个字节;也许你想到的是dec cx
?单字节的inc/dec操作码只适用于16或32位操作数大小,而不是8位。(如果你真的为了速度而优化,你会使用缓慢的loop
指令。但不要这样做) - Peter Cordesror di, 1
代替shr
来使它非破坏性。另外,你只设置了CX = 8,但DI和AX是16位寄存器。 - Peter Cordesror di,1
16 次,则 DI 的最终值将与初始值相同。但是,您的 shr
循环会使 DI=0(如果您进行了 16 次迭代)。因此,您可以选择哪个更有用:一个清零的寄存器还是原始值。 - Peter Cordes