指针指向的变量,右移一位高位不补"0",这是什么原因?

2020-01-13 18:25发布

本帖最后由 neutronlmk 于 2019-4-2 12:46 编辑

如下代码:
//指针
uint8_t test_tab[4];
uint8_t test_var;
uint8_t *p;
p = &test_tab[0];
*p = 0xFF;
(*p) >>= 1;//执行该条指令之后,test_tab[0]仍是0xFF。
//直接操作
test_var = 0xFF;
test_var >>= 1;//执行该条指令之后,test_var是0x7F,高位补"0"。
在多字节移位的情况下,移位之后高位不自动补“0”,需要多加好多代码来处理,低端的芯片空间不够扛不住。

我再编辑下,这个是匆忙精简出来的,指针赋值也错了。
另我看了汇编,使用指针移位汇编是按带进位的方式来移的。看来没法取巧利用移位补零的特性。
及——函数使用指针做参数,利用指针指向的变量输出结果,代码比直接使用全局变量大好多啊,足200字节。
芯片才1K~2K,不敢用。


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
liwei_jlu
1楼-- · 2020-01-14 11:44
没用到被优化了吧
t3486784401
2楼-- · 2020-01-14 14:07
本帖最后由 t3486784401 于 2019-4-2 17:21 编辑

不知是什么编译器,我看是 51 分论坛的,就用 KEIL C51 v8.12 试了试,没发现 LZ 说的问题。

2019-04-02_170333.png (2.68 KB, 下载次数: 0)

下载附件

2019-4-2 17:04 上传



不过 KEIL 优化很厉害的,如果程序最后一行是对某非 volatile 变量赋值,直接无视。

---------------------------------------------------------------------------------------------------------------------------------------

编辑原因:补充内容。

我又测试了 ICCAVR 编译器,一样没有出现 LZ 的问题,但是有一点需要注意:uint8_t 的定义不是标准 C。
所有测试都要加 typedef 这个定义(例如7楼)。但如果你定义错了,或者有疯狂的宏在作祟,就会有很作死的效果,例如:
typedef signed char uint8_t;
kebaojun305
3楼-- · 2020-01-14 16:49
估计就是6楼说得 数据类型得问题。
neutronlmk
4楼-- · 2020-01-14 19:58
 精彩回答 2  元偷偷看……
su33691
5楼-- · 2020-01-14 21:36
小容量的51核MCU,还是少用指针,直接操作数组。简单方便。
neutronlmk
6楼-- · 2020-01-14 22:31
su33691 发表于 2019-4-3 08:30
小容量的51核MCU,还是少用指针,直接操作数组。简单方便。

确实,我已经放弃使用指针。用指针的档案存起来做资料了。