【发布时间】:2014-08-10 13:51:18
【问题描述】:
在我正在做的任务中,我需要创建自己的库,其中应该包含一个函数来打印字符串(prints)、打印整数(printi)并返回打印的字符数。该库应使用内嵌汇编语言编写(不使用任何 stdio.h 库)
问题是一切正常,但我无法理解 printf 和 printi 的调用顺序。
这是我的代码:
我自己的 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
那么订单有什么问题...?
【问题讨论】:
-
从技术上讲,
fflush(stdin)是 C 中未定义的操作。某些平台支持将其作为扩展,但它不可移植。 -
通常,在同一个文件上使用
FILE *(如stdout)和文件描述符(如汇编程序中的1)不是一个好主意。或许可以通过调用write来替换printf。 (假设您的评论有错字,应该是// $4: write, $1: on stdout。) -
次要:考虑使用
char buff[sizeof(int)*CHAR_BITS/3 + 3]来避免使用幻数20。 -
@chux 对不起,我没看懂你的评论...... :(
-
代码使用
#define BUFF 20。为什么20特别?在您的系统上,20似乎 足够大是一个“幻数”:它的出现毫无道理。通过使用诸如sizeof(int)*CHAR_BITS/3 + 3之类的公式,所需的大小可以适应。如果int是64 位整数,BUFF将是24。如果int是16 位,BUFF将是8。如果int是128 位,BUFF将是45.
标签: c assembly printf inline-assembly