打印

stm32指令的特大BUG

[复制链接]
5309|38
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 IT工作者 于 2012-10-7 13:35 编辑

我用STM32F103CB的板子做了下实验,发现SSAT指令就是一个普通的移位运算指令,根本没有文档所说的饱和功能。比较坑爹,知道的大侠解释下,怎么回事?
附上测试代码,在MDK上编译,汇编代码,可用C代码调用。

     AREA |.text|, CODE, READONLY
     EXPORT  examfunc
examfunc
  PUSH    {lr}
  ssat r0,#31,r0,lsl #1
  POP      {pc}

   END

exam.zip

289 Bytes

沙发
airwill| | 2012-10-7 19:16 | 只看该作者
我特地用过这条指令, 跟指令所说完全符合, 怎么说是 BUG?
可能楼主理解错误了吧?
手册上说明:
有符号饱和到任何位位置,可选择在饱和前进行移位。
SSAT 可将有符号值饱和到有符号范围内。

使用特权

评论回复
板凳
IT工作者|  楼主 | 2012-10-7 20:07 | 只看该作者
饱和指令是做信号处理定点运算最基本的指令。

C语言这样调用:
int i = examfunc(0x7F221145);
按道理 i = 0x7fffffff;
但是实际 i = 0xFE44228A;

这个就是普通的移位运算。不是饱和运算,所以错了。
ST的CORTEX-M3怎么会这样,怎么回事?

使用特权

评论回复
地板
IT工作者|  楼主 | 2012-10-7 20:10 | 只看该作者
本帖最后由 IT工作者 于 2012-10-7 20:16 编辑

sorry,我笔误

请将 ssat r0,#31,r0,lsl #1

改成 ssat r0,#32,r0,lsl #1

按道理讲,31和32,得到的结果是不一样的,
31,结果是0x3FFFFFFF;
32,结果是0x7FFFFFFF;

但是 st 的cortex-m3 饱和指令ssat 没有饱和功能,就是个移位指令,所以无论31还是32,结果是一样的,0xFE44228A。

使用特权

评论回复
5
IT工作者|  楼主 | 2012-10-8 09:35 | 只看该作者
是否阉割版的CORTEX-M3?

使用特权

评论回复
6
IJK| | 2012-10-8 10:07 | 只看该作者
查这个问题应该不难。
MCU不选择STM32,而是选择CORTEX-M3类型,然后用软件仿真,看看结果是否有所不同。

使用特权

评论回复
7
IT工作者|  楼主 | 2012-10-8 10:21 | 只看该作者

+

本帖最后由 IT工作者 于 2012-10-8 10:24 编辑

抱歉,发多了
软仿真没直接在板子上跑可信,,SSAT指令既然存在,为什么没有应有的功能,这个问题怎么解释?

使用特权

评论回复
8
IJK| | 2012-10-8 12:13 | 只看该作者
抱歉,发多了
软仿真没直接在板子上跑可信,,SSAT指令既然存在,为什么没有应有的功能,这个问题怎么解释?
IT工作者 发表于 2012-10-8 10:21


软仿真跟STM32芯片跑比较,结果是否有所不同?

使用特权

评论回复
9
lvjing880907| | 2012-10-8 13:20 | 只看该作者
我怎么看不懂啊

使用特权

评论回复
10
IT工作者|  楼主 | 2012-10-8 15:12 | 只看该作者
在MDK(4.0以后版本,非最新版本,)软仿真和硬件跑确实是一样的。

但是ARM为什么要整这么坑爹的一个指令,这不摆明了胡弄人吗?

ARM的问题还是ST的问题?

使用特权

评论回复
11
IJK| | 2012-10-8 17:25 | 只看该作者
本帖最后由 IJK 于 2012-10-9 12:05 编辑
在MDK(4.0以后版本,非最新版本,)软仿真和硬件跑确实是一样的。

但是ARM为什么要整这么坑爹的一个指令,这不摆明了胡弄人吗?

ARM的问题还是ST的问题? ...
IT工作者 发表于 2012-10-8 15:12


我觉得,ARM和ST都没有问题。
记得CortexM3不支持饱和运算, CortexM4才支持饱和运算。
后来看了一眼,CortexM3支持SSAT指令。

使用特权

评论回复
12
IT工作者|  楼主 | 2012-10-8 20:36 | 只看该作者
本帖最后由 IT工作者 于 2012-10-8 20:45 编辑
我觉得,ARM和ST都没有问题。
记得CortexM3不支持饱和运算, CortexM3才支持饱和运算。
IJK 发表于 2012-10-8 17:25



没看明白   :L :Q

你也太无厘头了

使用特权

评论回复
13
IT工作者|  楼主 | 2012-10-8 20:38 | 只看该作者
STM32F103CB就是CortexM3。

而且,如果不支持,怎么能编译通过,还能运行该指令,怎么会有这么蹊跷的事。

有没有个权威的说法?

使用特权

评论回复
14
john_lee| | 2012-10-8 22:39 | 只看该作者
ssat指令的运算没有问题,是你自己没搞明白。

你在指令中给出的饱和位数是32,那么饱和范围就是−232−1 ≤ x ≤ 232−1−1 = 0x80000000 ≤ x ≤ 0x7FFFFFFF = −2147483648 ≤ x ≤  2147483647。

你给的运算参数是0x7F221145,左移一位(你在指令中写的lsl #1)后,这个值变为0xFE44228A,按有符号数来看,这个值是:−0x1BBDD76 = −29089142。可以看出,这个值是在饱和范围内的,当然不会变化。

你即使把饱和位数改成31,也是没有任何问题的。(范围变成了 −1073741824 ≤ x ≤ 1073741823)。

使用特权

评论回复
15
IT工作者|  楼主 | 2012-10-8 22:53 | 只看该作者
本帖最后由 IT工作者 于 2012-10-8 22:57 编辑

14楼的,正数都变成负数了,就是溢出了,饱和的意思是,溢出就返回正的最大数,或者负的最小数。

按你的逻辑,永运都不会饱和。饱和指令还有用么?

For signed n-bit saturation using SSAT, this means that:
• if the value to be saturated is less than −2n−1, the result returned is −2n-
• if the value to be saturated is greater than 2n−1−1, the result returned is
• otherwise, the result returned is the same as the value to be saturated.

使用特权

评论回复
16
john_lee| | 2012-10-8 23:07 | 只看该作者
0x7F221145 是正数,但左移一位就变成负数 0xFE44228A 了。这个有啥不明白的?

使用特权

评论回复
17
zchong| | 2012-10-9 09:04 | 只看该作者
15# IT工作者

楼主理解的有问题啊

可以这样理解,你把移位后的数放到这条指令中,是不是就是这个结果,没有饱和

这个明白之后,其它就好理解了

使用特权

评论回复
18
IT工作者|  楼主 | 2012-10-9 09:29 | 只看该作者
16,17楼的,不明白,我也不能强迫你能明白。

我现在只希望官方辟谣。

使用特权

评论回复
19
IJK| | 2012-10-9 12:30 | 只看该作者
The SSAT instruction applies the specified shift, then saturates to the signed range -2^sat-1 ≤ x ≤ 2^sat-1 -1

使用特权

评论回复
20
IJK| | 2012-10-9 12:40 | 只看该作者
SSAT 指令做的操作如19L解释。

ssat r0,#32,r0,lsl #1
上面这条指令,首先 把r0左移1位【lsl是逻辑左移,当然可以正数变负数】,所以0x7F221145变为0xFE44228A ,其它解释看14L【14L已经解释得很清楚】。

LZ 应该在前面的某个地方想偏了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

33

帖子

0

粉丝