使用printf和我自己的打印打印顺序

时间:2014-08-10 13:51:19

标签: c assembly printf inline-assembly

在我正在进行的任务中,我需要创建自己的lib,其中应包含打印字符串(prints)的函数,打印整数(printi)并返回打印的字符数。该库应使用内联汇编语言编写(不使用任何stdio.h库)

问题是一切正常,但我无法理解调用printfprinti的顺序。

这是我的代码:

我自己的myl库:

/* 
 * print_int.c 
 * A system call to print an integer 
 */
#include "myl.h"  // my own library
#define BUFF 20

int printi(int n){  // my own printi function to print numbers
    char buff[BUFF], zero='0';
    int i=0, j, k, bytes;

    // saveN = n;
    if(n == 0) buff[i++]=zero;
    else{
        if(n < 0) {
            buff[i++]='-';
            n = -n;
        }
        while(n){
            int dig = n%10;
            buff[i++] = (char)(zero+dig);
            n /= 10;
        }
        if(buff[0] == '-') j = 1;
        else j = 0;
        k=i-1;
        while(j<k){
            char temp=buff[j];
            buff[j++] = buff[k];
            buff[k--] = temp;
        }
    } 
    // buff[i]='\n';
    bytes = i;

    __asm__ __volatile__ (
      "movl $4, %%eax \n\t"
      "movl $1, %%ebx \n\t"
      "int $128 \n\t"
      :
      :"c"(buff), "d"(bytes)
    ) ;  // $4: write, $1: on stdin

    return bytes;
}


int prints(char *str){  //my own prints function to print strings
    int i;
    for (i = 0; str[i]!='\0'; ++i) {}

  __asm__ __volatile__ (
    "movl $4, %%eax \n\t"
    "movl $1, %%ebx \n\t"
    "int $128 \n\t"
    :
    :"c"(str), "d"(i)
    ) ;  // $4: write, $1: on stdin
    return i;
}

和我的test.c文件:

#include <stdio.h>
#include "myl.h"
int main()
{ 
    int n,k;
    char s[100];
    printf("Please enter a string: ");
    fflush(stdin);
    scanf("%[^\n]",s);
    k=prints(s);
    printf("\nNO of chars printed = ");

    printi(k);  // number of chars printed
    return 0;
}

一切正常,但在NO of chars printed =被打印之前,正在打印k ..

这是终端显示的内容:

Please enter a string: asdf
asdf
4NO of chars printed =

我希望它是:

Please enter a string: asdf
asdf
NO of chars printed =4

所以订单错了......?

3 个答案:

答案 0 :(得分:0)

fflush(stdout);之后立即尝试printf()。它可能是缓冲输出。

答案 1 :(得分:0)

当stdout是终端时,printf()默认进行行缓冲。这意味着它不会调用实际的write()系统调用,除非它看到\n个字符。因此,您的printi()首先打印,当程序退出时,字符串将从缓冲区中刷新。

您应该使用自己的非缓冲prints()

fflush(stdout);之后立即printf

答案 2 :(得分:0)

可以禁用stdout缓冲区,调用:

setbuf (stdout,NULL);

在main的开头插入它,允许混合stdout和你的实现保持调用顺序。