3

*我正在使用程序集 8086 (x86-32)

交易很简单,我在寄存器 AL 中有一个字节大小的数字(8 位),现在,我需要在寄存器中的数字的第 1 位(右二)和第 4 位(右五)之间进行交换铝。

例如:如果 Al 有这个数字:00010000B 现在它将有 00000010B。

谢谢!

4

5 回答 5

5

一对二指令回答:

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 条指令(取决于某个寄存器是否已知包含零或位掩码)。

或者,如果 & 掩码仅设置了一个位,则可以选择测试。这是通过表达式 (a== (a&-a)) 完成的

于 2012-11-03T10:12:22.147 回答
3

你可以试试这个:

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

end 追加到末尾

pop BX
于 2012-11-03T08:47:05.040 回答
1

另一种选择(7 条指令):

mov ebx,00010010b         ;ebx = 00010010
and ebx,eax               ;ebx = 000A00B0
lea ebx,[ebx+ebx*4]       ;ebx = 0A0AB0B0
rol bl,5                  ;ebx = AB0B00A0
and ebx,00010010b         ;ebx = 000B00A0
and al,11101101b          ;al = abc0ef0g
or  al,bl                 ;al = abcBefAg

还有另一种选择(也是 7 条指令):

ror al,1           ;ax = ????????.gabcAefB
ror ax,1           ;ax = B???????.?gabcAef
ror al,3           ;ax = B???????.Aef?gabc
rol ax,1           ;ax = ???????A.ef?gabcB
rol al,3           ;ax = ???????A.gabcBef?
ror al,1           ;ax = ????????.AgabcBef
rol al,2           ;ax = ????????.abcBefAg
于 2012-11-03T09:19:46.930 回答
1

我添加了我的六个指令替代方案:

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 指令集。

于 2012-11-03T10:00:58.083 回答
1

单独使用 al 的 6 条指令

           ; 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
于 2012-11-03T10:08:31.247 回答