关于51单片机使用printf的bug
51单片机使用printf可能会出bug,比如printf("%X",0),打印结果实际是FF,猜测是printf函数不适合八位单片机。有两种解决方法,一是使用printf("%X",(int)0)强行补0,还有就是用特殊的占位符%bd,%bx等等 历史遗留问题Win32/64上,现在编译器 %X 都是4字节32位长度
TurboC编译器,这种16位编译器,2字节16位长度
C51是个差不多等同于ANSIC(C89),
printf("%X" <这个输出16位
,0); <由于8位环境,最小字节优化,这个是个8位数值
看到的是FF
实际是00FF,00忽略,所以得到FF,没毛病
51年代太久远了 本帖最后由 JuncoJet 于 2024-7-24 12:09 编辑
差不多等效于这个结果 00什么时候回等于00ff,0就是0扩展成00000000都不会变成00 ffffff或者0000ffff或者000000ff aidn 发表于 2024-7-24 12:25
00什么时候回等于00ff,0就是0扩展成00000000都不会变成00 ffffff或者0000ffff或者000000ff
不是扩展问题,栈里结构问题
0是1一个字节,%X 2个字节,输出时0在栈里旁边是啥跟着显示啥 bug是肯定的了。
这个事情看起来是个类型提升的问题。 自己不会用不要乱说。
原因是Keil C51中的printf()与标准的C库的printf()函数不一样。
使用C51的printf()函数打印%d/i/u/o/x/X格式时,你必须要指定该变量的存储格式l/L/b/B。
如果定义的变量c为char类型时。
printf("%bd\n",c);
printf("%bu\n",c);
printf("%bx\n",c);
c为uint16时,则需将%bd等改为%hd;
c为uint32时,则需将%bd等改为%ld;
就是必须要指定该变量的存储格式,这样做也是为了节约资源,毕竟8位处理器资源较少。 本帖最后由 MF35_ 于 2024-7-24 15:56 编辑
我告诉你真正的原因把,上面说的都不太准确
首先C51是大端地址模式,而我们的PC是小端地址模式,如果你不明白什么是小端大端,百度吧
其次,C51库的printf是符合标准C库定义的
标准C库对printf中i、d、o、x、X使用的类型是int,对u使用的类型是unsigned int
而在C51编译器中,int是16位的,但C51的堆栈是1字节对齐的,对于没有规定形参长度的情况(比如print的未知参数),在参数入栈时,如果给入的实参是立即数(即没有规定实参的存储类型),那么编译器会按照能够存储该立即数的最小内存长度来入栈,也就是说0这个立即数会被当作字节入栈,而printf是不知道的。当printf解析到x的时候,它认为参数表里是个int,于是去参数表取了一个16位的数出来,这个16位数的地址和存入的字节0相同,但由于地址是大端的,所以0后面一个字节的内容被认为是int的低字节了,这个值是随机的,而你这里正好是0xff,所以整个16位的int就变成0x00ff了,由于你没有规定打印x的有效位个数,所以只打印两个ff,前面的00是不打印的
而你用printf("%x", (int)0)时,等于告诉编译器,把0这个值按照int类型入栈,所以不会出错,或者你使用print("%bx", 0)时,等于告诉编译器,取参数的时候按照字节取,所以也不会出错。
所以问题不在函数库,而是你没有理解printf函数以及编译器的工作原理
所谓形参,就是函数定义的时候规定的参数类型,比如
void func(int a)
这个函数中的a就是形参,它是int类型,你调用func函数时,你传入的任何能与int兼容的类型都会被转换为int入栈,比如func(0)时,0就一定会被按int入栈而不是字节
而printf函数的定义是
int printff(const char *fmt, ...),看到后面的...了吗?这个就是不确定形参,对于不确定形参,C标准无法规定如何入栈,因此入栈方式是编译器决定的,在32位PC上,每个参数都必须至少是4字节,所以对于32位pc上的printf("%x", 0)调用,0是被当作32位数入栈的,对于64位pc,则是8字节入栈,即便你强制说明参数是1字节,也是按照4字节或8字节入栈,这就是处理器要求的堆栈对齐
而C51是8位机,它没有堆栈对齐,或者说它是1字节堆栈对齐,也就是如果编译器不知道一个参数的存储类型,它会尽可能以1字节入栈,比如
printf("%x", 0),此时0是1字节入栈(char型)
printf("%x", (int)0),此时0是2字节入栈(int型,因为你告诉了编译器存储类型)
printf("%x", 512),此时512则是2字节入栈(int型) 究其本质,其实就是编译器如何处理立即数的问题
立即数本身是没有存储类型的,比如0,比如1200,C编译器处理立即数的时候,会按照立即数值的大小与默认机器字长度去预设它的存储类型,比如0这个值,在1字节字长的机器上(即8位机)可以存储在1字节中,那么就当作1字节,而1200不能,就当作2字节。而在4字节字长的机器上(即32位机)可以存储在1字节中,但由于机器字长是4字节,所以它被当作4字节。
除非你给立即数加后缀,比如你写0I,意思是int类型的0,那么编译器就会按照机器的int类型去存储0,比如你写0L,就会按照long类型存储,同理还有0U和0UL。
或者你给出强制转换,比如(int)0或者(long)0,也是告诉编译器,强制按照这个类型存储。
但为什么我们在计算表达式中使用立即数时,即便没有强制转换,也没有给定后缀,依然能够正确计算呢?因为C语言在计算表达式的时候,表达式中的所有的存储类型,都会被临时扩展到表达式中最大的存储类型来计算,比如
int a = 0;
这个表达式中最大的变量长度是int,所以0被当作int传递给a,又比如
int a = 10;
char b = 1;
int c = a + 3 - b;
在c的表达式中,最大的变量长度是int,所以0被当作int处理,而b被扩展到int再计算 _main:
; c1.c:14: printf("a=%d,b=%d\n",a,b);
mov a,#0x12
push acc
clr a
push acc
mov a,#0xbb
push acc
clr a
push acc
mov a,#___str_0
push acc
mov a,#(___str_0 >> 8)
push acc
mov a,#0x80
push acc
lcall _printf
mov a,sp
add a,#0xf9
mov sp,a
; c1.c:16: return 0;
mov dptr,#0x0000
; c1.c:17: }
ret
.area CSEG (CODE)
.area CONST (CODE)
.area CONST (CODE)
___str_0:
.ascii "a=%d,b=%d"
.db 0x0a
.db 0x00
.area CSEG (CODE)
.area XINIT (CODE)
.area CABS (ABS,CODE)
#include <stdio.h>
int putchar(int c)
{
return c;
}
int
main(void)
{
char a=0xaabb;
char b=0x12;
printf("a=%d,b=%d\n",a,b);
return 0;
这个事,显然和编译器有关系,我觉着和printf的实现也有关系。
我手里没用51单片机,也没模拟器。我直接看的汇编部分。linux环境,sdcc编译器。
~/tmp$ uname -a
Linux P7 5.10.0-29-amd64 #1 SMP Debian 5.10.216-1 (2024-05-03) x86_64 GNU/Linux
~/tmp$ sdcc --version
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ez80_z80/ds390/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15 4.0.0 #11528 (Linux)
published under GNU General Public License (GPL)
~/tmp$
本帖最后由 ssffzz1 于 2024-7-24 18:02 编辑
~/tmp$ sdcc -o c1 c1.c
c1.c:11: warning 158: overflow in implicit constant conversion
~/tmp$
sdcc在编译的时候,提示值溢出。代码中也只传了个0xbb,虽然真实的参数宽度是16bit。具体printf的执行我没法测试,没实物了,而模拟器未必靠谱。
keil环境没有。
总之这个东西和具体的实现有关。算bug吧。当然不算也可以。 51也好,32也好,这个命令不靠谱,我都是把数据分离后再传送的。 感谢楼主辛苦的分享
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSNhc2
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSNhc2
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSMCcm
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSMCcm
h5.weishi.qq.com/weishi/feed/7SYcCKTu51SxSKYaC
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCKTu51SxSKYaC
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCKTu51SxSK5uC
h5.weishi.qq.com/weishi/feed/7SYcAsevj1SxSKiO8
h5.weishi.qq.com/weishi/feed/7SYcCKTu51SxSK5uC
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAsevj1SxSKiO8
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSJVgg
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCKTu51SxSJOOA
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSJVgg
h5.weishi.qq.com/weishi/feed/7SYcCKTu51SxSJOOA
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSJN8E
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSJN8E
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAsevj1SxSJJMW
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSJK4K
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSJK4K
h5.weishi.qq.com/weishi/feed/7SYcAsevj1SxSJJMW
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSJzCF
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSJzCF
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSJzWc
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSJzWc
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAsevj1SxSJscw
h5.weishi.qq.com/weishi/feed/7SYcAsevj1SxSJscw
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSJrGs
h5.weishi.qq.com/weishi/feed/7SYcCyj2S1SxSJi0k
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSJrGs
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCyj2S1SxSJi0k
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSJig4
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSJig4
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSJgOm
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSJgOm
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSJeOy
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSJeOy
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSJbK4
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSJbK4
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCKTu51SxSJ74U
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98as1SxSJ0iq
h5.weishi.qq.com/weishi/feed/7SYcCKTu51SxSJ74U
h5.weishi.qq.com/weishi/feed/7SYcC98as1SxSJ0iq
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSJ2mo
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSJ2mo
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSIY8m
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSIRQu
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSIRQu
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSIY8m
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSIQYo
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSIQYo
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7g1SxSIJSC
h5.weishi.qq.com/weishi/feed/7SYcBco7g1SxSIJSC
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSIIw2
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSIIw2
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSIFE8
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSIFE8
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBSlA71SxSID8c
h5.weishi.qq.com/weishi/feed/7SYcBSlA71SxSID8c
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSIEqy
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSIEqy
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98as1SxSIDmY
h5.weishi.qq.com/weishi/feed/7SYcC98as1SxSIDmY
h5.weishi.qq.com/weishi/feed/7SYczn69U1SxSIwES
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczn69U1SxSIwES
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSIvC6
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSIvC6
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSIs4C
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSIs4C
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSIs4Y
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSIs4Y
h5.weishi.qq.com/weishi/feed/7SYcBco7g1SxSIksE
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7g1SxSIksE
h5.weishi.qq.com/weishi/feed/7SYcC98ar1SxSIjG2
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98ar1SxSIjG2
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSIjK8
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSIjK8
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSIgYA
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSIgYA
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcC98as1SxSIeqm
h5.weishi.qq.com/weishi/feed/7SYcC98as1SxSIeqm
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczn69U1SxSId6a
h5.weishi.qq.com/weishi/feed/7SYczn69U1SxSId6a
h5.weishi.qq.com/weishi/feed/7SYcBco7g1SxSI9u8
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7g1SxSI9u8
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSI76g
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSI76g
h5.weishi.qq.com/weishi/feed/7SYcCdkjv1SxSI2uS
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcCdkjv1SxSI2uS
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7g1SxSHXg2
h5.weishi.qq.com/weishi/feed/7SYcBco7g1SxSHXg2
h5.weishi.qq.com/weishi/feed/7SYczn69U1SxSHPs4
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczn69U1SxSHPs4
h5.weishi.qq.com/weishi/feed/7SYcBco7k1SxSHIsk
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7k1SxSHIsk
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSHH0e
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSHH0e
h5.weishi.qq.com/weishi/feed/7SYcAo2ma1SxSHzEm
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAo2ma1SxSHzEm
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAo2ma1SxSHr6w
h5.weishi.qq.com/weishi/feed/7SYcAo2ma1SxSHr6w
h5.weishi.qq.com/weishi/feed/7SYcziU0O1SxSHoQA
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcziU0O1SxSHoQA
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSHm8u
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSHm8u
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcBco7g1SxSHj80
h5.weishi.qq.com/weishi/feed/7SYcBco7g1SxSHj80
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSHbkM
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSHbkM
h5.weishi.qq.com/weishi/feed/7SYcAo2ma1SxSH9uO
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcAo2ma1SxSH9uO
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSH0CO
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSH0CO
h5.weishi.qq.com/weishi/feed/7SYcziU0O1SxSH6se
h5.weishi.qq.com/weishi/feed/7SYczavIA1SxSGVgM
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcziU0O1SxSH6se
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczavIA1SxSGVgM
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczeHRG1SxSGPeC
h5.weishi.qq.com/weishi/feed/7SYczeHRG1SxSGPeC
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSGM0w
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSGM0w
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczn69U1SxSGL0M
h5.weishi.qq.com/weishi/feed/7SYczn69U1SxSGL0M
h5.weishi.qq.com/weishi/feed/7SYcziU0O1SxSGLA8
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcziU0O1SxSGLA8
h5.weishi.qq.com/weishi/feed/7SYczeHRG1SxSGzOY
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczeHRG1SxSGzOY
h5.weishi.qq.com/weishi/feed/7SYczn69U1SxSGsAs
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczn69U1SxSGsAs
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczeHRG1SxSGqsQ
h5.weishi.qq.com/weishi/feed/7SYczeHRG1SxSGqsQ
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczavIz1SxSGi06
h5.weishi.qq.com/weishi/feed/7SYczavIz1SxSGi06
h5.weishi.qq.com/weishi/feed/index.html?id=7SYcz6jzp1SxSG6Qk
h5.weishi.qq.com/weishi/feed/7SYcz6jzp1SxSG6Qk
h5.weishi.qq.com/weishi/feed/index.html?id=7SYczvus41SxSG4WY
h5.weishi.qq.com/weishi/feed/7SYczvus41SxSG4WY
h5.weishi.qq.com/weishi/feed/7SYcziU0O1SxSFXAm
页:
[1]