欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

研究试验5

程序员文章站 2022-06-07 09:38:53
...

研究试验5

函数如何接受不确定参数

编写a.c ,解答 相关问题

  1. main 是如何给 showchar 传递参数的?
  2. showchar 是如何接受参数?

a.c

  • c 代码

    void showchar(char a, int b);
    
    main()
    {
        showchar('a', 2);
    }
    
    void showchar(char a, int b)
    {
        *(char far *)(0xb8000000 + 160 * 10 + 2 * 40) = 'a';
        *(char far *)(0xb8000000 + 160 * 10 + 2 * 40 + 1) = 2;
    }
    
  • 汇编代码

    研究试验5

    研究试验5

问题解答

  1. main函数通过 栈 给 showchar 传递参数

    研究试验5

  2. showchar 应该也是从栈中获取的但是汇编代码中没有相关的栈操作。

编写 b.c 思考相关问题

  1. showchar 函数是要如何知道呀显示多少个字符的?
  2. printf函数是如何知道有多少个参数的?

b.c

  • c 代码

    void showchar(int, int, ...);
    
    main()
    {
        showchar(8, 2, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h');
    }
    
    void showchar(int n, int color, ...)
    {
        int a;
        for (a = 0; a != n; a++)
        {
            *(char far *)(0xb8000000 + 160 * 10 + 80 + a + a) = *(int *)(_BP + 8 + a + a);
            *(char far *)(0xb8000000 + 160 * 10 + 81 + a + a) = color;
        }
    }
    
  • 汇编代码

    研究试验5

    研究试验5

    研究试验5

    研究试验5

    研究试验5

printf 函数是如何知道有多少给参数

  • 先写一个 printf.c 的测试用例

    main(){
        printf("%c,%c,%c,%c",'a','b','c','d');
        printf("%d,%d,%d,%d",1,2,3,4);
    }
    
  • 汇编代码

    • 第一个printf

      研究试验5

    • 第二个 printf

      研究试验5

    • 通过对照 printf 函数 可以猜想 mov ax,0194;mov ax 01a0 因该是 printf的第一个参数,然后通过 debug 可以验证猜想是正确的

      研究试验5

      通过观察可以看到 25 63 2c 25 63 2c 25 63 2c 25 63 2c 25 63 00 对应 字符串 %c,%c,%c,%c25 64 2c 25 64 2c 25 64 2c 25 64 00 对应字符串 %d,%d,%d,%d,,故根据以往编程经验猜想 00 为终止条件。所以把第三个 %c 对应的汇编代码开头改变为 00,看看是不是只输出两个字符 通过下图可以看出猜想正确。所以可以得出printf可能是根据传入的%的个数来确定打印的字符数,读入一个%就会读取后面一个字符来确定打印的方式,当读出一个0时打印结束

      研究试验5

问题解答

  1. 第一个参数 n 就是告知函数 showchar显示多少给字符
  2. printf是通过 %的个数来得知有多少个参数,通过 00来判断结束。

实现一个简单的 printf 函数 只需支持 %c,%d 即可

void myPrintf(char *, ...);

main()
{
    myPrintf("xxxxx%c,%n,ddddd%d", 'x', 5);
}

void myPrintf(char *str, ...)
{
    int stackIndex = 0;
    int stringIndex = 0;
    int screenIndex = 0;
    int screenBenchmark = 160 * 10;

    while (str[stringIndex] != 0)
    {
        if (str[stringIndex] == '%')
        {
            if (str[stringIndex + 1] == 'c')
            {
                *(char far *)(0xb8000000 + screenBenchmark + screenIndex) = *(char *)(_BP + 6 + stackIndex); /*跨 push call 第一个参数 才能取到相应的值*/
                *(char far *)(0xb8000000 + screenBenchmark + screenIndex + 1) = 2;
                screenIndex += 2;
                stringIndex += 2;
                stackIndex += 2;
            }
            else if (str[stringIndex + 1] == 'd')
            {
                *(char far *)(0xb8000000 + screenBenchmark + screenIndex) = *(char *)(_BP + 6 + stackIndex) + 0x30;
                *(char far *)(0xb8000000 + screenBenchmark + screenIndex + 1) = 2;

                stackIndex += 2;
                screenIndex += 2;
                stringIndex += 2;
            }
            else if (str[stringIndex + 1] == 'n')
            {
                screenBenchmark += 160;
                screenIndex = 0;
                stringIndex += 2;
            }
        }
        else
        {
            *(char far *)(0xb8000000 + screenBenchmark + screenIndex) = str[stringIndex];
            *(char far *)(0xb8000000 + screenBenchmark + screenIndex + 1) = 2;

            screenIndex += 2;
            stringIndex += 1;
        }
    }
}
相关标签: 王爽汇编