我在微处理器类中,我们在飞思卡尔CodeWarrior中使用汇编语言来编程68HCS12微控制器。我们本周的任务是反转一个字节,所以如果字节是00000001,输出将是10000000,或者是00101011到11010100.我们必须使用汇编语言,并被告知我们可以使用旋转和移位(但不限于! )完成这项任务。我真的不知道应该从哪里开始。
答案 0 :(得分:8)
提示:如果你进行了一次移位,一位被移出,一个零(可能)被移入。那里移出的位去了哪里?您需要将其移入目标寄存器或存储器地址的另一端。
我敢肯定25年前我可以在没有汇编程序的Z80机器代码中执行此操作:)
答案 1 :(得分:7)
将两个寄存器视为位堆栈。如果你一次一个地移动一个到另一个会发生什么?
答案 2 :(得分:6)
如果可以节省256字节的额外代码大小,查找表可能是反转68HCS12上字节的最有效方法。但我很确定这不是教练所期待的。
对于“普通”解决方案,请分别考虑数据位。旋转和移位允许您移动位。对于第一种解决方案,隔离8位(按位“和”操作),将它们移动到目标位置(移位,旋转......),然后再将它们组合在一起(使用按位“或”操作)。这不是最有效或最简单的实现,但您应该首先集中精力获得正确的结果 - 优化可以等待。
答案 3 :(得分:3)
首先解决算法以完成您需要做的事情。将其表示为伪代码或C或普通英语或图表或您喜欢的任何内容。一旦你清除了这个概念上的障碍,实际的实现应该非常简单。
您的CPU可能具有允许您移位和/或旋转寄存器的指令,可能包括进位标志作为附加位。这些说明非常有用。
答案 4 :(得分:3)
当你进行右移时,最低有效位进入进位标志。
当你进行旋转时,进位标志用于填充结果的空位(ROL为LSB,ROR为MSB)。
答案 5 :(得分:3)
例如,如果你有字节数,最简单的方法是
mov al, 10101110
mov ecx, 8
我们在ecx for loop中放了8个
mov ebx, 0
在bl中我们将得到结果,我们将制作ebx,只是为了看看会发生什么更好
loop1:
sal al, 1;
在进位标志中,你现在有了左边的最后一位
rcr bl, 1;
现在你添加了你携带的内容
loop loop1
这就是
答案 6 :(得分:1)
这是评论,但我想WTH!
为了节省256字节表上的空间,您可以拥有一个16字节的表,一次包含四位(半字节)的值。那么算法就是
revval=(revdigit[inval&0x0f]<<4)|
revdigit[inval>>4];
如果我是一名教授,我当然喜欢这两个部分,其中一个班次在索引中,另一个在外部。
答案 7 :(得分:0)
我还要对大学进行反向编程(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:
我没有评论它,所以这里是如何工作的:
DH是1
,它像第一次一样在字节中传播:00000001
;第二次00000010
等等。当您使用AL AND
获得0
或100
或10000
之类的内容时,您必须将其移至右侧才能获得0
或1
。
然后,将其放入BH并移至所需位置,7
表示字节0
,6
表示字节1
,依此类推。然后OR
到我们的最终结果,INC
和DEC
必要的。不要忘记条件跳转并为下一个循环弹出AX
:)
结果将在CH。
答案 8 :(得分:0)
以下代码利用旋转和移位。我使用Intel x86语法,请参阅右侧的说明:
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占用3个字节。最重要的是,编译器似乎总是通过选择dec over sub来进行优化。
edit:还请注意,rcl ax
(3个字节),而与adc ax, 0
(2个字节)后跟shl ax
(2个字节)等效。
请参阅下面的评论,非常感谢Peter Cordes的见解。
答案 9 :(得分:-1)
您所说的第一件事,就是将1000变成0001与不叫它是另一回事。 (应该只是一个周期。)