Assembly 在asm中向左换档,然后立即向右换档?

Assembly 在asm中向左换档,然后立即向右换档?,assembly,arm,bit-shift,Assembly,Arm,Bit Shift,免责声明:我是asm新手。我可能需要复习我的2s补语或一些东西来完全理解:( 我对以下内容的目的感到困惑: .... BL some_func MOV R3, R0,LSL#16 MOVS R3, R3,LSR#16 .... 为什么要向后移位?而MOV在左移位时,溢出的位将丢失。因此,32-16=16位以上的所有位将在右移位后归零 r0 = aaaabbbbccccdddd eeeeffffgggghhhh lsl, 16 -> aaaab

免责声明:我是asm新手。我可能需要复习我的2s补语或一些东西来完全理解:(

我对以下内容的目的感到困惑:

....
BL some_func
MOV R3, R0,LSL#16
MOVS R3, R3,LSR#16
....

为什么要向后移位?而MOV在左移位时,溢出的位将丢失。因此,32-16=16位以上的所有位将在右移位后归零

     r0 =                   aaaabbbbccccdddd eeeeffffgggghhhh
lsl, 16 -> aaaabbbbccccdddd eeeeffffgggghhhh 0000000000000000
             (overflowed)
        ->                  eeeeffffgggghhhh 0000000000000000
lsr, 16 ->                                   eeeeffffgggghhhh
该指令相当于

r3 = r0 & 0xffff;

在左移位中,溢出的位将丢失。因此,在右移位后,32-16=16位以上的所有位将被清零

     r0 =                   aaaabbbbccccdddd eeeeffffgggghhhh
lsl, 16 -> aaaabbbbccccdddd eeeeffffgggghhhh 0000000000000000
             (overflowed)
        ->                  eeeeffffgggghhhh 0000000000000000
lsr, 16 ->                                   eeeeffffgggghhhh
该指令相当于

r3 = r0 & 0xffff;

执行r0&=0xFFFF需要三条指令

mov r3,#0x00FF orr r3,r3,#0xFF00 and r0,r0,r3 mov r3,#0x00FF orr r3,r3,#0xFF00 和r0,r0,r3 因此,来回转换效率更高

您所做的可能与16位变量有关,因此为了准确起见,编译器必须截断高位以使程序正常运行。如果您使用int或其他方法,它可能没有做到这一点,但不确定这是否是您发出这些指令的方式

有时你会看到这是一个符号扩展,但这不是一个算术移位,而是一个逻辑移位(零不是进位)

也许您的代码执行了类似if(hello&0xFFFF)then的操作

ARM通常不会更新标志,除非您告诉它,否则出于性能原因(如果没有其他类似的代码)

if(a&0xFF) b=0x12; else b=0x34; would be something like: ands r0,r0,#0xFF movne r1,#0x12 moveq r1,#0x34 如果(a&0xFF)b=0x12;否则b=0x34; 大概是这样的: 和r0,r0,#0xFF 移动r1,#0x12 移动q r1,#0x34 对于其他处理器,and将始终设置标志,下一条指令将是导致管道刷新的分支

ands r0,r0,#0xFF bne notequal mov r1,#0x12 b wasequal notequal: mov r1,#0x34 wasequal: 和r0,r0,#0xFF bne notequal mov r1#0x12 b是相等的 注: mov r1#0x34 平等: 执行时更加残酷。许多处理器也会用move immediate覆盖标志,而arm不会这样做。(拇指模式是另一回事)

arm上的每条指令都有一个条件字段,而不仅仅是分支有一个条件字段,分支如果相等,如果相等,添加如果相等,子如果相等,分支如果进位集,如果进位集等等。同样,可以修改标志的指令有一个操作码位,用于启用或禁用标志更新。您可以添加而r0,r1,r2不更新标志,但r0,r1,r2会更新标志


因此,您的两条指令做了两件事它将寄存器的上16位置零,然后为随后的任何条件设置标志。对于可能是分支(如果相等)或分支(如果不相等)。生成此结果的原始源代码是什么样子的?

执行r0&=0xFFFF需要三条指令

mov r3,#0x00FF orr r3,r3,#0xFF00 and r0,r0,r3 mov r3,#0x00FF orr r3,r3,#0xFF00 和r0,r0,r3 因此,来回转换效率更高

您所做的可能与16位变量有关,因此为了准确起见,编译器必须截断高位以使程序正常运行。如果您使用int或其他方法,它可能没有做到这一点,但不确定这是否是您发出这些指令的方式

有时你会看到这是一个符号扩展,但这不是一个算术移位,而是一个逻辑移位(零不是进位)

也许您的代码执行了类似if(hello&0xFFFF)then的操作

ARM通常不会更新标志,除非您告诉它,否则出于性能原因(如果没有其他类似的代码)

if(a&0xFF) b=0x12; else b=0x34; would be something like: ands r0,r0,#0xFF movne r1,#0x12 moveq r1,#0x34 如果(a&0xFF)b=0x12;否则b=0x34; 大概是这样的: 和r0,r0,#0xFF 移动r1,#0x12 移动q r1,#0x34 对于其他处理器,and将始终设置标志,下一条指令将是导致管道刷新的分支

ands r0,r0,#0xFF bne notequal mov r1,#0x12 b wasequal notequal: mov r1,#0x34 wasequal: 和r0,r0,#0xFF bne notequal mov r1#0x12 b是相等的 注: mov r1#0x34 平等: 执行时更加残酷。许多处理器也会用move immediate覆盖标志,而arm不会这样做。(拇指模式是另一回事)

arm上的每条指令都有一个条件字段,而不仅仅是分支有一个条件字段,分支如果相等,如果相等,添加如果相等,子如果相等,分支如果进位集,如果进位集等等。同样,可以修改标志的指令有一个操作码位,用于启用或禁用标志更新。您可以添加而r0,r1,r2不更新标志,但r0,r1,r2会更新标志


因此,您的两条指令做了两件事:将寄存器的上16位置零,然后为随后的任何条件设置标志。对于可能是分支(如果相等)或分支(如果不相等)的mov。您最初的源代码是什么样子生成的?

@borealid-谢谢,我一直在寻找实际的源代码n asm@starblue就是这样arm@borealid-谢谢,我一直在寻找asm@starblue上的实际课件,它主要回答了我的问题…至少是我问的问题;)我遗漏了一条数据,在这一点上r0是一个很小的值,所以我看不出得到了什么。。。我更新了主要回答我问题的问题。。。至少是我问的那个;)我遗漏的一条数据是r0在那个点上是一个很小的值,所以我看不出得到了什么。。。我更新了问题谢谢你的详细回答…我还在努力摸索。。。我没有写原始代码,这是分解的结果谢谢你的详细回复…我仍在努力摸索这一切。。。我没有编写原始代码,它是反汇编的结果