找回密码
 立即注册
查看: 783|回复: 20

STC15程序移植到STC32时发现,Keil中指针变量做函数参数,C51和C251 编译有区别!

[复制链接]

该用户从未签到

1

主题

7

回帖

27

积分

新手上路

积分
27
发表于 2024-2-23 17:41:00 | 显示全部楼层 |阅读模式
问题不太容易描述,直接看代码:

typedef unsigned char        uint8;
typedef unsigned int        uint16;

uint8 xdata buf_xdata[9] _at_ 0x0200;

void test(uint8 *pt)
{
        uint8 i;
        for(i = 0; i < 3; i++) *pt++ = i;
}

void main()
{
        uint8 xdata *pt;//指向xdata区
        uint16 addr;

        test((uint8 xdata *)0x0200);        //此行可得正常结果 buf_xdata[0] = 0x00; buf_xdata[1] = 0x01; buf_xdata[2] = 0x02;
       
        pt = 0x0203;
        test(pt);                                        //此行可得正常结果 buf_xdata[3] = 0x00; buf_xdata[4] = 0x01; buf_xdata[5] = 0x02;
       
        addr = 0x0206;
        test((uint8 xdata *)addr);                //此行在STC32系列单片机C251中编译得不到预期结果!但在STC15系列单片机C51中编译可正确执行
                                                        //预期结果:buf_xdata[6] = 0x00; buf_xdata[7] = 0x01; buf_xdata[8] = 0x02;
        while(1);
}

test()函数的参数是指针

(uint8 xdata *)0x0200 -----地址0x0200(常量)强制转化为指向xdata区的指针,正常

pt = 0x0203;-----指向xdata区的指针pt赋值0x0203,正常

addr = 0x0206;-----变量赋值0x0206,然后强制转化为指向xdata区的指针,C51正常,C251就不正常

想不明白,哪位大神能给指点一二,谢谢

回复 送花

使用道具 举报

  • TA的每日心情
    开心
    昨天 21:50
  • 签到天数: 152 天

    [LV.7]常住居民III

    34

    主题

    325

    回帖

    653

    积分

    高级会员

    积分
    653
    发表于 2024-2-24 09:53:56 | 显示全部楼层
    我试过用C51移值,发现函数的参数,不能用公式直接代入,需要在外现处理好,例如
    uint8 xdata *pt;//指向xdata区   
    pt = 0x0203;
    test(pt);   

    但是如果你直接
    addr = 0x0206;
    test((uint8 xdata *)addr);
    就会报错。

    还有addr = 0x0206;
    test((uint8 xdata *)addr);   这个还有个问题,一般先定义addr为指针,然后再给addr赋值,   但是你这个是先给ADDR定义一个16位(有可能得定义32位),然后再强制转化。
    纸上得到终觉浅,绝知此事要躬行。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-5 08:35
  • 签到天数: 143 天

    [LV.7]常住居民III

    29

    主题

    558

    回帖

    2140

    积分

    荣誉版主

    积分
    2140
    发表于 2024-2-24 10:28:25 | 显示全部楼层
    本帖最后由 gentleman 于 2024-2-24 10:32 编辑

    测试了一下
    测试环境 屠龙刀-STC32G12K128
    打印数组  没发现问题

    检查其他方面吧
    截图202402241028039623.jpg




    回复 支持 1 反对 0 送花

    使用道具 举报

  • TA的每日心情
    开心
    11 小时前
  • 签到天数: 175 天

    [LV.7]常住居民III

    9

    主题

    856

    回帖

    3361

    积分

    论坛元老

    积分
    3361
    发表于 2024-2-24 10:34:41 | 显示全部楼层
    addr = 0x0206;-----变量赋值0x0206,然后强制转化为指向xdata区的指针,C51正常,C251就不正常
    因为这么操作,他的地址就不是在xdata了,是在edata了。
    STC32G_pt01.png







    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    20

    主题

    575

    回帖

    1191

    积分

    荣誉版主

    积分
    1191
    发表于 2024-2-24 11:24:41 | 显示全部楼层
    我个人的理解:
    addr是16位,通用指针是32位,强制转换时,自动高位补0导至指针指向了edata区. C51不会有这种事情。
    强制转换有时候是不安全的转换,比如32位转16位,编绎器只是按照默认规则转换数据,不能保证转换结果一定正确.
    编辑代码时尽量考虑可以多种环境运行。
    尝试一下改成这样:
    test((uint8 xdata *)0+addr);

    test(&((uint8 xdata *)0)[addr]);



    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    7

    回帖

    27

    积分

    新手上路

    积分
    27
     楼主| 发表于 2024-2-24 18:33:06 | 显示全部楼层
    飞捷 发表于 2024-2-24 09:53
    我试过用C51移值,发现函数的参数,不能用公式直接代入,需要在外现处理好,例如
    uint8 xdata *pt;//指向xd ...

    addr定义为32位也不行
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    7

    回帖

    27

    积分

    新手上路

    积分
    27
     楼主| 发表于 2024-2-24 18:39:19 | 显示全部楼层
    本帖最后由 programshao 于 2024-2-24 18:46 编辑
    tzz1983 发表于 2024-2-24 11:24
    我个人的理解:
    addr是16位,通用指针是32位,强制转换时,自动高位补0导至指针指向了edata区. C51不会有 ...

    大佬提供的方法是可行的。

    我不理解的是:
    常量0x0200(或者0)在经过(uint8 xdata *)的强制转换时,会将高位补上0x01,即0x010206,从而指向xdata区;
    但是变量addr=0x0206在经过(uint8 xdata *)的强制转换时,却会将高位补成0,就指向了edata区了
    为何会有这种差异?

    点评

    可能是常量赋值指针时编绎自动处理类型,变量不处理.可以分别以常量和变量赋值然后printf()看看,如果是这样就没必要深究了, 毕竞是使用者迎合编译器  发表于 2024-2-24 21:49
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    7

    回帖

    27

    积分

    新手上路

    积分
    27
     楼主| 发表于 2024-2-24 18:55:31 | 显示全部楼层
    gentleman 发表于 2024-2-24 10:28
    测试了一下
    测试环境 屠龙刀-STC32G12K128
    打印数组  没发现问题

    能不能发我完整的工程文件看看?我怀疑是不是跟编译条件有关?

    点评

    刚才实测了一下, 无论是立即数赋值还是变量赋值,编绎器都自动补全高位,编绎器没有问题。支持gent***的说法,检查其它方面原因 [attachimg]36040[/attachimg]  详情 回复 发表于 2024-2-26 09:17
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    2024-5-5 08:35
  • 签到天数: 143 天

    [LV.7]常住居民III

    29

    主题

    558

    回帖

    2140

    积分

    荣誉版主

    积分
    2140
    发表于 2024-2-25 08:18:02 | 显示全部楼层
    编译环境
    xSmall -large

    工程见附件



    截图202402250815513642.jpg




    05-串口1中断模式与电脑收发测试 - 副本.7z

    79.79 KB, 下载次数: 15

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 21:50
  • 签到天数: 152 天

    [LV.7]常住居民III

    34

    主题

    325

    回帖

    653

    积分

    高级会员

    积分
    653
    发表于 2024-2-26 00:26:41 | 显示全部楼层
    programshao 发表于 2024-2-24 18:33
    addr定义为32位也不行

    最后找出原因了吗?
    纸上得到终觉浅,绝知此事要躬行。
    回复 支持 反对 送花

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-17 12:15 , Processed in 0.116216 second(s), 72 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表