Assembly 如何在汇编中交换字节数中的2位
*我使用的是汇编8086(x86-32) 交易非常简单,我在寄存器AL中有一个字节大小的数字(8位), 现在,我需要在寄存器AL中数字的第1位(从右数第二位)和第4位(从右数第五位)之间进行交换 例如:如果Al有这个数字:000100000B,现在它将有00000010B 谢谢大家! 您可以尝试以下方法:Assembly 如何在汇编中交换字节数中的2位,assembly,x86,bit-manipulation,Assembly,X86,Bit Manipulation,*我使用的是汇编8086(x86-32) 交易非常简单,我在寄存器AL中有一个字节大小的数字(8位), 现在,我需要在寄存器AL中数字的第1位(从右数第二位)和第4位(从右数第五位)之间进行交换 例如:如果Al有这个数字:000100000B,现在它将有00000010B 谢谢大家! 您可以尝试以下方法: mov BL, AL mov BH, AL and BL, 2h //empty all bits except first and BH, 10h //empty all bits
mov BL, AL
mov BH, AL
and BL, 2h //empty all bits except first
and BH, 10h //empty all bits except fourth
shl BL, 3 //move bit 1 to position of bit 4
shr BH, 3 //move bit 4 to position of bit 1
and AL, edh //empty first and fourth bits
or AL, BL //set bit 4
or AL, BH //set bit 1
AL寄存器包含结果。此外,您可能需要存储在寄存器BX中的数据。如果您这样做,则在溶液前添加
push BX
结束追加到结束
pop BX
另一种选择(7种说明):
和另一个备选方案(也是7个说明):
我添加了我的六个指令选项:
xor bl, bl ; -> clear work register
btr ax, 1 ; -> second bit to carry, clear that bit in al
cmovc bl, 8 ; -> set bit at bitpos 3
btr ax, 4 ; -> fifth bit to carry, clear that bit in al
rcl bl, 2 ; -> set bit at bitpos 2, shift bitpos 3 -> 5
or al, bl ; -> merge bits
注:这只是一个学术练习。您可能不想要使用btr指令的代码,因为这些指令很慢。至少上次我试着用过。另外:未经测试
需要486条指令集。6条指令仅使用al
; al | cf
; 76543210 | x
ror al, 5 ; 43210765 | x
bt al, 4 ; 43210765 | 1
rcl al, 4 ; 07651432 | 1
bt al, 2 ; 07651432 | 4
rcr al, 3 ; 32407651 | 4
rol al, 4 ; 76513240 | x
一到两个说明回答:
and eax, $255; // mask off extra bits -- perhaps not needed, if upper bits are
mov al, look_up_table[eax] // guaranteed to be zero
仅使用al的三个指令
test al, $0x12
jpe skip ;; parity was even (aka the bits are the same)
xor al, $0x12 ;; toggle both bits
skip:
操作原理:只有当位不同时才需要交换位。
0更改为1,1通过与1异或将其更改为0。
两个位同时受到影响
如果存在条件cmovpo或cmovpe,则可以避免跳转。但在这种情况下,序列至少需要4条指令(取决于已知某个寄存器是否包含零或位掩码)
或者,如果&mask只有一个位集,则可以选择测试。这是用表达式(a==(a&-a))完成的非常感谢!现在我要想办法提高你的工资reputation@user1461085:如果答案解决了您的问题,您可以通过单击此答案旁边的复选标记给他15分。:)这也让人们知道哪个答案对你帮助最大,所以无论如何,这是鼓励的。我试图在这里放置最简单的解决方案,但Aki的解决方案是最苗条的!选择权在你。注:答案左边的勾号为空;)。哇!这是我第一次看到使用奇偶校验位,经过近20年的asm编码。CMOV.cc必须用有效的寻址模式(例如16或32位reg/reg移动,或从内存读取)替换。出于某种原因,英特尔没有立即采取行动。
and eax, $255; // mask off extra bits -- perhaps not needed, if upper bits are
mov al, look_up_table[eax] // guaranteed to be zero
test al, $0x12
jpe skip ;; parity was even (aka the bits are the same)
xor al, $0x12 ;; toggle both bits
skip: