2010-08-16 58 views
1

免责声明:我是一个ASM新手。我可能需要检查我的二进制补什么的充分理解:(左移,然后立即右移在ASM?

我很困惑,以下目的:??

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

为什么向后移位和MOVS

+0

http://net.pku.edu.cn/~course/cs201/2003/mirrorWebster.cs.ucr.edu/Page_asm/ArtofAssembly/ch15/CH15-2.html#HEADING2-1 – Borealid 2010-08-16 03:14:01

+0

什么处理器,ARM ? – starblue 2010-08-16 12:26:33

+0

@borealid - 谢谢,我一直在寻找关于asm的实际课件 @starblue这是手臂 – 2010-08-16 12:44:26

回答

2

在左移,溢出的位将遗失。上述因此,所有位32-16 = 16位将右移之后清零。

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

指令相当于

r3 = r0 & 0xffff; 
+0

,主要是回答我的问题...至少我问的一个;) 我遗漏的一个数据是,r0是一个小值在那一点,所以我没有看到获得什么...我更新了问题 – 2010-08-16 12:51:22

+0

没关系......咖啡没有工作...我得到它:) – 2010-08-16 12:53:22

3

它有三个指令做一个R0 & = 0xFFFF的

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

所以移位来回更有效率。

你可能一直在做的事情是关于一个16位变量,所以为了准确,编译器必须截断高位以使程序正常运行。你是否使用了int或者它可能没有做到这一点,不知道你是如何煽动这些指令的。

有时候你会看到这样做来做一个符号扩展,但这不是一个算术转换,它是一个逻辑转换(零进位而不是进位位)。

也许你的代码做了类似if(你好& 0xFFFF)那么。

ARM不能正常更新标志,除非你告诉它,出于性能的考虑,如果像这样

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

与其他处理器没有别的代码,并总是设置标志和下一个指令将是一个导致管道冲洗的分支。

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

执行时更残酷。许多处理器会用立即移动的方式覆盖标志,而手臂不能这样做。 (拇指模式是另一回事)。

而不是只有有条件字段的分支,手臂上的每条指令都有一个条件字段,如果相等则分支,如果相等,则相加时相加,相等时相加,如果进位置分支,并且如果进位等。同样,可以修改标志的指令具有一个操作码位,用于启用或禁用标志的更新。您将这些s添加到指令中。并且r0,r1,r2不是,而是r0,r1,r2更新标志。

所以你的两条指令做了两件事情,它将寄存器的高16位清零,然后设置标志以表示接下来的任何条件。对于可能是分支的mov,如果相等,则分支。你最初的源代码看起来是什么产生的?

+0

感谢您的详细回复...即时通讯仍然试图把它全部......我没有写出原来的代码,这是一个反汇编的结果 – 2010-08-17 13:36:33