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 装配轮班/旋转_Assembly_Rotation_Shift - Fatal编程技术网

Assembly 装配轮班/旋转

Assembly 装配轮班/旋转,assembly,rotation,shift,Assembly,Rotation,Shift,这些是问题: 我有这个硬件,但我只知道基本知识。如果有人能给我一个关于如何解决这些问题的提示,那将是一个很大的帮助。我知道这可能是一个绝望的举动,但至少我会学会如何回答这类问题。在这种情况下,您可以使用位逻辑-逻辑and和OR设置并清除整数值的部分 表面示例:我有位值0101;我想设置最低的两位。所以我还是用0011。现在我想清除两个最低的位。因此,如果两个输入位都是1,则I和with 1100.“AND”仅返回1。 0和0是0 1和0是0 0和1是0 1和1是1 所以“清除”位可以通过与0“

这些是问题:


我有这个硬件,但我只知道基本知识。如果有人能给我一个关于如何解决这些问题的提示,那将是一个很大的帮助。我知道这可能是一个绝望的举动,但至少我会学会如何回答这类问题。

在这种情况下,您可以使用位逻辑-逻辑and和OR设置并清除整数值的部分

表面示例:我有位值0101;我想设置最低的两位。所以我还是用0011。现在我想清除两个最低的位。因此,如果两个输入位都是1,则I和with 1100.

“AND”仅返回1。
0和0是0
1和0是0
0和1是0
1和1是1

所以“清除”位可以通过与0“anding”来完成。无论位(b)是什么,b和0都是0

如果任一输入位为1,“或”返回1。
0或0是0
1或0是1
0或1是1
1或1是1

“设置”位可通过使用1“ORing”完成。无论位(b)是什么,b或1都是1

AX是16位的 如果使用0000.1111.1111.1111b(=0x0FFF)和AX,则最顶端的半字节(4位)将被清除
(如果使用1,则不会更改任何位,如果设置为1,则保持为1,如果设置为0,则保持为未设置,因此所有不应更改的半字节将与1进行AND)

如果您使用0000.0000.0000.1111b(=0x000F)或AX,则下半字节将全部设置。

(或者使用0时不会有任何变化,如果设置为1,则保持为1,如果设置为0,则保持为未设置,因此所有其他半字节都使用0进行或运算)

理解这些操作的最佳方法是一步一步地遍历它们。我会尽力解释这个过程。在每一步中,我都会包括两个寄存器的状态,以便您可以继续操作。为了保持EAX的上限值,我们必须首先将其内容移动到另一个寄存器中进行操作

开始:
EAX:0011100 1001 1111 1011 1100 1001 1111

mov-ebx,eax;将eax的内容复制到ebx中

EAX:001110011111110111001111111
EBX:0011100 1001 1111 1011 1100 1001 1111

shl-ebx,24;这将清除ebx中我们不关心的位
shr-ebx,24;移回初始位置

EAX:001110011111110111001111111
EBX:0000 0000 1100 1001

shl-ebx,4;向左移动4位。bx是我们下一步需要它的地方

EAX:001110011111110111001111111
EBX:0000 0000 11001001 0000

添加bl,0Fh;将0xF添加到bl。或以二进制形式添加到1111。最小有效半字节集

EAX:001110011111110111001111111
EBX:0000 0000 1100 1001 1111

异或ax,ax;清除ax中的内容,为bx中的内容腾出空间

EAX:0011100 1001111 0000
EBX:0000 0000 1100 1001 1111

添加ax、bx;将bx的结果合并回eax以获得最终结果

EAX:0011100 1001 1111 0000 1100 1001 1111

就在这里!既然您已经熟悉了轮班操作,我将把最后一部分留给您

干杯

  • 要清除AX的最高有效位半字节并设置最低有效位半字节,可以编写:

    and ax, 0FFFh  ;Clears the top nibble
    or  ax, 000Fh  ;Sets the bottom nibble
    
    没有
    /
    ,使用轮班:

    shl ax, 4      ;Moves the middle part into AH
    mov al, 0F0h   ;Prepares for a set low nibble
    shr ax, 4      ;Puts everything in place
    
    shl ax, 1      ;Calculate 2*AX
    mov dx, ax     ;Store in DX
    shl ax, 2      ;Continue calculating 8*AX
    add ax, dx     ;Makes AX = 8*AX + 2*AX
    
  • 要使用移位计算10*AX,请执行以下操作:

    shl ax, 4      ;Moves the middle part into AH
    mov al, 0F0h   ;Prepares for a set low nibble
    shr ax, 4      ;Puts everything in place
    
    shl ax, 1      ;Calculate 2*AX
    mov dx, ax     ;Store in DX
    shl ax, 2      ;Continue calculating 8*AX
    add ax, dx     ;Makes AX = 8*AX + 2*AX
    

  • 你只需要轮班吗?2听起来像是和/或的工作。3听起来不可能只使用shift或rotate。听起来像是LEA的工作(在相同的insn中进行移位和添加):
    LEA-ecx,[rcx*2]
    /
    LEA-eax,[rcx+8*rax]
    。或者更简单地说,使用x2、x5执行x10:
    shl eax
    /
    lea eax,[rax+4*rax]
    通常使用“清除”而不是“删除”。删除意味着它们不再是寄存器的一部分,而不是它们仍然存在并设置为零。