XIVN1987 发表于 2013-1-7 14:01:13

Cortex-M中有符号数右移是逻辑右移还是算术右移???


Cortex-M指令集中关于移位的指令有以下三条:
ASRS    {Rd,} Rn,<Rs|#imm>      算术右移
LSLS    {Rd,} Rn,<Rs|#imm>      逻辑左移
LSRS    {Rd,} Rn,<Rs|#imm>      逻辑右移

而C语言中用于移位的运算符只有“<<"和">>"两个,其中”<<"运算符毫无疑问对应LSLS运算,即不管是对应有符号数还是无符号数一律右边补零;那对于">>"运算符到底是执行算术右移ASRS呢?还是执行逻辑右移LSRS呢??

我在网上搜了一下,发现网上说:对于">>"的具体实现,C语言标准中并没有规定,而是具体的CPU实现相关的。。即可以是逻辑右移,也可以是算术右移,具体是什么看实现。。


我在MDK下测试了一下有符号数的">>"运算,发现执行的是算术右移。。但不知道这个是不是ARM强制规定的,还是MDK规定的,,如果我写了有符号数的右移运算,那么在MDK、IAR和GCC之间行为是一样的吗???


希望了解具体规定的大侠指点一下!!!谢谢了!!

dr2001 发表于 2013-1-7 14:44:49

C99标准中对移位运算的语义定义:
<<,无符号是左移;有符号正数,移位后如果计算结果能被正确表达,则是左移;剩下的情况都是未定义行为。(理解:有符号正数左移要求最高为1的那个位不能移动到符号位。等价于根据移位前的值,限制了可以进行的移位范围。)
>>,无符号逻辑右移;有符号数正数>>始终是高位补0(逻辑/算数都行);有符号负数是Implementation Defined。(理解:实际上这个给没有算数移位的处理器留了个空子,逻辑右移也没问题。)
详见C99标准6.5.7。

未定义行为是说标准没规定,咋样都行。
实现定义的行为要求文档说明。


GCC的实现:
目前(截止到4.7.2),<<是逻辑左移;>>无符号是逻辑,有符号是算数。
http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Integers-implementation.html#Integers-implementation

Keil MDK的实现:
截止到4.60,<<是逻辑左移;>>无符号是逻辑,有符号是算数。
armccref.chm (Compiler Reference Guide), C and C++ Implementation Details, C and C++ Implementation Details, Operations on basic data types.

XIVN1987 发表于 2013-1-7 19:12:46

dr2001 发表于 2013-1-7 14:44 static/image/common/back.gif
C99标准中对移位运算的语义定义:
,无符号逻辑右移;有符号数正数>>始终是高位补0(逻辑/算数都行);有符 ...


大侠讲解的非常明白透彻,非常感谢!!!多谢大侠指教!!
页: [1]
查看完整版本: Cortex-M中有符号数右移是逻辑右移还是算术右移???