-
Notifications
You must be signed in to change notification settings - Fork 5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于"Merge pull request #1836 from RT-Thread/fix_fputc"的问题 #1837
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
此提交后代码如下:
int fputc(int c, FILE *f)
{
char ch[2] = {0};
}
注: 为了跟踪调用fputc时传入c参数.按以下步骤修改测试
int main(void)
{
/* user app entry */
printf("test"); // 增加,为了调用fputc
return 0;
}
main
0x8020019C : PUSH {r4,lr}
0x8020019E : ADR r0,{pc}+0xa ; 0x802001a8
0x802001A0 : BL __2printf ; 0x8020C2F8 // 这个时printf函数
0x802001A4 : MOVS r0,#0
0x802001A6 : POP {r4,pc}
0x802001A8 : DCD 0x74736574 // 这个是字符串"test"
0x802001AC : DCD 0x00000000
__2printf
0x8020C2F8 : LDR r2,[pc,#4] ; [0x8020C300] = 0x8020C0B9 // 这是fputc地址(+1为thumb指令)
0x8020C2FA : LDR r1,[pc,#8] ; [0x8020C304] = 0x80400218 // 这里是__stdout变量.
0x8020C2FC : B.W _printf_core ; 0x8020C326
0x8020C300 : DCD 0x8020C0B9
0x8020C304 : DCD 0x80400218
_printf_core
0x8020C326 : PUSH {r4-r8,lr}
0x8020C32A : MOV r6,r2 // fputc
0x8020C32C : MOV r7,r1
0x8020C32E : MOV r4,r0
0x8020C330 : MOVS r5,#0
0x8020C332 : B _printf_core+22 ; 0x8020C33C
0x8020C334 : MOV r1,r7
0x8020C336 : BLX r6 // fputc
0x8020C338 : ADDS r4,r4,#1
0x8020C33A : ADDS r5,r5,#1
0x8020C33C : LDRB r0,[r4,#0] // 读取字符串中一个字符到r0,作为fputc第1个参数c
0x8020C33E : CMP r0,#0
0x8020C340 : BNE _printf_core+14 ; 0x8020C334
0x8020C342 : MOV r0,r5
0x8020C344 : POP {r4-r8,pc}
根据"LDRB r0,[r4,#0] "判断, fputc第1个参数c,只有第1个字节有效,第2/3/4个字节都为0.这个与armclang编译器返汇编结果一致. 因此fputc应该修改如下:
int fputc(int c, FILE f)
{
rt_kprintf((char)&c);
return 1;
}
并且fputc/fgetc的__MICROLIB限定应该取消,对应armcc不使用microlib或armclang的情形,这两个函数都需要,否则printf等函数将不正常.
上面这个更改是最高效的. 下面这种是看不到汇编代码,无法确定传入c的第2~4字节数值时的改动:
int fputc(int c, FILE f)
{
((char)&c)[1] = '\0'; // 各编译器在调这个函数前,准备的字符c,应该都会保证2/3/4字节为0.
rt_kprintf((char*)&c);
return 1;
}
The text was updated successfully, but these errors were encountered: