将系统调用与linux上的printf混合使用
我在汇编调用c函数时做了一些测试,当我使用ansi转义码并调用使用printf的c函数时,我得到了我认为的奇怪行为.
这是装配部分: section .data red db 27,"[31;1m",0 redlen equ $- red cyan db 27,"[36;1m",0 cyanlen equ $- cyan colorReset db 27,"[0m",0 colorResetLen equ $- colorReset section .text extern printLetter extern letter global main main: mov BYTE [letter],'H' call ansiSetRed call printLetter mov BYTE [letter],'e' call ansiSetCyan call printLetter mov BYTE [letter],'l' call ansiReset call printLetter mov BYTE [letter],'l' call ansiSetRed call printLetter mov BYTE [letter],'o' call ansiSetCyan call printLetter mov BYTE [letter],'!' call ansiReset call printLetter mov BYTE [letter],10 call printLetter ret ansiSetRed: mov rax,1 mov rdi,1 mov rsi,red mov rdx,redlen syscall ret ansiSetCyan: mov rax,cyan mov rdx,cyanlen syscall ret ansiReset: mov rax,colorReset mov rdx,colorResetLen syscall ret 看起来很长,但我所做的只是在开头用ansi代码定义一些字符串,一个用于将前景色设置为红色,一个用于青色,一个用于重置颜色. 然后我有使用syscall write打印这个ansi字符串的函数. 主要功能是打印“你好!”通过首先调用打印相应ansi字符串的汇编函数,然后调用extern c函数来打印存储在全局变量中的字符,来交替每个字母的颜色. 这里是c部分: #include <stdio.h> char letter; void printLetter(void) { printf("%c",letter); } 当我运行它时,消息“你好!”如果装配零件没有打印ansi代码,则显示全白色 但如果我改变c部分只是在每个字符后面打印一个新行: #include <stdio.h> char letter; void printLetter(void) { printf("%cn",letter); } 然后这些字母显示我开始时预期的每种颜色中的一种颜色. 这种行为的原因是什么? 解决方法
那是因为如果stdout进入终端,stdio(C标准I / O包)对stdout使用行缓冲.这意味着您编写的数据不会立即发送到终端,而是缓冲直到整行可用.你在第一个程序中观察到的(你好,在一行上)是在用一个换行符调用printLetter之前,实际上没有写入Hello的字符,导致stdout的缓冲区被刷新到终端.
我看到了以下解决问题的方法(其中任何一个都可以解决问题,但只使用一种方法): >编辑ansiSetRed等来调用fwrite而不是直接执行write系统调用.这应该使缓冲按预期工作.>调用setbuf(stdout,NULL)以在写入任何数据之前关闭缓冲.>写入stderr而不是stdout,因为stderr是无缓冲的>在每个printf之后执行fflush(stdout)以手动刷新stdout.>重写printLetter以使用系统调用write而不是printf. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |