Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 如何在汇编中交换字节数中的2位_Assembly_X86_Bit Manipulation - Fatal编程技术网

Assembly 如何在汇编中交换字节数中的2位

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

*我使用的是汇编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 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: