1

免责声明:我是 asm 新手。我可能需要复习我的 2s 补码或其他东西才能完全理解 :(

我对以下目的感到困惑:

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

为什么要转回来?和movs?

4

2 回答 2

3

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

mov r3,#0x00FF
orr r3,r3,#0xFF00
和 r0,r0,r3

所以来回切换更有效率。

What you may have been doing is something related to a 16 bit variable so to be accurate the compiler has to truncate the upper bits to make the program operate properly. had you used int or something it may not have done this, not sure if that is how you instigated these instructions.

Sometimes you will see this to do a sign extension but this was not an arithmetic shift it was a logical shift (zeros coming in not the carry bit).

Maybe your code did something like if(hello&0xFFFF) then.

ARM does not update the flags normally unless you tell it to, for performance reasons if nothing else code like this

if(a&0xFF) b=0x12; else b=0x34;
would be something like:
ands r0,r0,#0xFF
movne r1,#0x12
moveq r1,#0x34

With other processors the and would always set the flags and the next instruction would be a branch causing a pipe flush.

ands r0,r0,#0xFF
bne notequal
mov r1,#0x12
b wasequal
notequal:
mov r1,#0x34
wasequal:

Much more brutal when executed. Many processors would overwrite the flags with the move immediate as well, which the arm doesnt do. (thumb mode is another story).

Instead of only branches having a conditional field, every instruction on the arm has a conditional field, branch if equal, and if equal, add if equal, sub if equal, branch if carry set, and if carry set, etc. And likewise the instructions that can modify flags have an opcode bit that enables or disables the update of the flags. You add the s to the instruction. and r0,r1,r2 does not but ands r0,r1,r2 does update the flags.

So your two instructions did two things it zeroed out the upper 16 bits of a register then set the flags for whatever conditional that followed. For a mov that was likely a branch if equal or branch if not equal. What did your originally source code look like that generated this?

于 2010-08-16T17:02:39.033 回答
2

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

     r0 =                   aaaabbbbccccdddd eeeeffffgggghhhh
lsl, 16 -> aaaabbbbccccdddd eeeeffffgggghhhh 0000000000000000
             (overflowed)
        ->                  eeeeffffgggghhhh 0000000000000000
lsr, 16 ->                                   eeeeffffgggghhhh

该指令相当于

r3 = r0 & 0xffff;
于 2010-08-16T12:28:30.487 回答