大锤子 发表于 2024-9-17 15:36:58

求助关于SDCC使用--stack-auto 编译选项后功能不正常

下边这段代码是实现根据入参计算矩形X轴方向的结束位置,来画电池电量:
void LCD_ShowPower(u16 power) {

// 计算横坐标的结束位置
unsigned int dis, xend;

dis = power*38/3300;
xend = dis + 263;
LCD_Fill(263,16,xend,32,WHITE);

LCD_DrawRectangle(260, 13, LCD_W - 16, 13+22, WHITE); // 首先画出电池的轮廓
LCD_Fill(LCD_W - 15, 21,LCD_W - 12, 27, WHITE);
}但是效果并没有达到预期, 其中电池的轮廓和正极能正常画出来。但是中间的填充画不出来,如视频显示:



这个文件的编译命令:
sdcc -o .pio/build/STC8H8K64U/libdea/LCD/lcd.rel -c --opt-code-size --peep-return -mmcs51 --model-large --stack-auto --std-c99 --less-pedantic -DF_CPU=35000000L -DHEAP_SIZE=128 -DPLATFORMIO=60115 -DSTC8H8KXXU -DSTC8H8K64U -DNAKED_ARCH_MCS51 -DNAKED_MCS51_STC8H8KXXU -DPIO_OS_CPU_MAIN_CLOCK=35000000L -Ilib/LCD/src -I.pio/libdeps/STC8H8K64U/STC8G_H_LIB/include -I.pio/libdeps/STC8H8K64U/STC8G_H_LIB/src lib/LCD/src/lcd.c

下边是这个函数的汇编程序:
;------------------------------------------------------------
;Allocation info for local variables in function 'LCD_ShowPower'
;------------------------------------------------------------
;power                     Allocated to registers r6 r7
;dis                     Allocated to registers
;xend                      Allocated to registers r6 r7
;------------------------------------------------------------
;        lib/LCD/src/lcd.c:377: void LCD_ShowPower(u16 power) {
;        -----------------------------------------
;       function LCD_ShowPower
;        -----------------------------------------
_LCD_ShowPower:
        mov        r6,dpl
        mov        r7,dph
;        lib/LCD/src/lcd.c:382: dis = power*38/3300;
        push        ar6
        push        ar7
        mov        dptr,#0x0026
        lcall        __mulint
        mov        r6,dpl
        mov        r7,dph
        dec        sp
        dec        sp
        mov        a,#0xe4
        push        acc
        mov        a,#0x0c
        push        acc
        mov        dpl,r6
        mov        dph,r7
        lcall        __divuint
        mov        r6,dpl
        mov        r7,dph
        dec        sp
        dec        sp
;        lib/LCD/src/lcd.c:383: xend = dis + 263;
        mov        a,#0x07
        add        a,r6
        mov        r6,a
        mov        a,#0x01
        addc        a,r7
        mov        r7,a
;        lib/LCD/src/lcd.c:384: LCD_Fill(263,16,xend,32,WHITE);
        mov        a,#0xff
        push        acc
        push        acc
        mov        a,#0x20
        push        acc
        clr        a
        push        acc
        push        ar6
        push        ar7
        mov        a,#0x10
        push        acc
        clr        a
        push        acc
        mov        dptr,#0x0107
        lcall        _LCD_Fill
        mov        a,sp
        add        a,#0xf8
        mov        sp,a
;        lib/LCD/src/lcd.c:386: LCD_DrawRectangle(260, 13, LCD_W - 16, 13+22, WHITE); // 首先画出电池的轮廓
        mov        a,#0xff
        push        acc
        push        acc
        mov        a,#0x23
        push        acc
        clr        a
        push        acc
        mov        a,#0x30
        push        acc
        mov        a,#0x01
        push        acc
        mov        a,#0x0d
        push        acc
        clr        a
        push        acc
        mov        dptr,#0x0104
        lcall        _LCD_DrawRectangle
        mov        a,sp
        add        a,#0xf8
        mov        sp,a
;        lib/LCD/src/lcd.c:387: LCD_Fill(LCD_W - 15, 21,LCD_W - 12, 27, WHITE);
        mov        a,#0xff
        push        acc
        push        acc
        mov        a,#0x1b
        push        acc
        clr        a
        push        acc
        mov        a,#0x34
        push        acc
        mov        a,#0x01
        push        acc
        mov        a,#0x15
        push        acc
        clr        a
        push        acc
        mov        dptr,#0x0131
        lcall        _LCD_Fill
        mov        a,sp
        add        a,#0xf8
        mov        sp,a
;        lib/LCD/src/lcd.c:390: }
        ret

将程序中的send写死后想要的效果如下:







大锤子 发表于 2024-9-17 18:05:42

测试了下, dis = power*38/3300; 这段的结果是 -1. 感觉像是堆栈中的值被误改了。 但是程序执行到这里还没有开启中断。 应该不会被改。 会不会是栈溢出?

大锤子 发表于 2024-9-20 22:01:52

这个问题解决了。在大明狐 大佬的指点下,将参数改成 float 就能得到准确结果了。
但是遇到了新的问题,尝试用相同的办法解决不太行;

不使用编译的时候只使用 --model-large结果是正确的, 使用了再加上 --stack-auto 就错了;

感觉像是栈溢出。






大锤子 发表于 2024-9-21 21:24:51

问题解决了。。。。。

我感觉不是我的锅。

sdcc的文档没有说连接也需要这个选项,

比如文档中--model-large 写的就很明确:



但是stack-auto 就没有说link也需要:

Snapdragon 发表于 2024-11-27 13:22:05

大锤子 发表于 2024-9-21 21:24
问题解决了。。。。。

我感觉不是我的锅。


好像我之前也碰到过,不过当时是单纯玩玩就没后续了,有空我试试是不是也是这个原因{:5_290:}
页: [1]
查看完整版本: 求助关于SDCC使用--stack-auto 编译选项后功能不正常