`
lobin
  • 浏览: 444317 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C:不定长参数相关操作va_list,va_start,va_arg,va_end

 
阅读更多

 

不定长参数传递问题

void kprintf(char *fmt, ...) 
{
  char* p;

  va_list vl;
  
  va_start(vl, fmt);
  //_asm lea ax,word ptr [bp+6];
  //_asm mov di,ax;

  for (p = fmt; *p; p++)
  {
	char c = *p;
	if (c == '$') break;
    if (c == '%')
    {
	  //char v;

      char v = va_arg(vl, char);
	  //_asm add di,2;
	  //_asm mov al,byte ptr ss:[di-2];

	  //_asm mov v, al;
	  _int10_0e(v);
    }
	else 
	{
	  _int10_0e(c);
	}
  }
  
  va_end(vl);
}

 对应汇编代码:

000302ab: (                    ): push bp                   ; 55
000302ac: (                    ): mov bp, sp                ; 8bec
000302ae: (                    ): sub sp, 0x0002            ; 83ec02
000302b1: (                    ): push si                   ; 56
000302b2: (                    ): push di                   ; 57
000302b3: (                    ): lea ax, word ptr ss:[bp+6] ; 8d4606
000302b6: (                    ): mov di, ax                ; 8bf8
000302b8: (                    ): mov si, word ptr ss:[bp+4] ; 8b7604
000302bb: (                    ): jmp .+53                  ; eb35
000302bd: (                    ): mov al, byte ptr ds:[si]  ; 8a04
000302bf: (                    ): mov byte ptr ss:[bp-1], al ; 8846ff
000302c2: (                    ): cmp byte ptr ss:[bp-1], 0x24 ; 807eff24
000302c6: (                    ): jnz .+2                   ; 7502
000302c8: (                    ): jmp .+45                  ; eb2d
000302ca: (                    ): cmp byte ptr ss:[bp-1], 0x25 ; 807eff25
000302ce: (                    ): jnz .+23                  ; 7517
000302d0: (                    ): add di, 0x0002            ; 83c702
000302d3: (                    ): mov bx, di                ; 8bdf
000302d5: (                    ): mov al, byte ptr ds:[bx-2] ; 8a47fe
000302d8: (                    ): mov byte ptr ss:[bp-2], al ; 8846fe
000302db: (                    ): mov ah, 0x0e              ; b40e
000302dd: (                    ): mov al, byte ptr ss:[bp-2] ; 8a46fe
000302e0: (                    ): mov bx, 0x000f            ; bb0f00
000302e3: (                    ): int 0x10                  ; cd10
000302e5: (                    ): jmp .+10                  ; eb0a
000302e7: (                    ): mov ah, 0x0e              ; b40e
000302e9: (                    ): mov al, byte ptr ss:[bp-1] ; 8a46ff
000302ec: (                    ): mov bx, 0x000f            ; bb0f00
000302ef: (                    ): int 0x10                  ; cd10
000302f1: (                    ): inc si                    ; 46
000302f2: (                    ): cmp byte ptr ds:[si], 0x00 ; 803c00
000302f5: (                    ): jnz .-58                  ; 75c6
000302f7: (                    ): pop di                    ; 5f
000302f8: (                    ): pop si                    ; 5e
000302f9: (                    ): mov sp, bp                ; 8be5
000302fb: (                    ): pop bp                    ; 5d
000302fc: (                    ): ret                       ; c3

 另一个例子:

void args(char *prefix, ...)
{
  va_list vl;
  char c;

  va_start(vl, prefix);
  c = va_arg(vl, char);

  _asm mov ah, 0eh;
  _asm mov al, c;
  _asm mov bx, 0fh;
  _asm int 10h;

  va_end(vl);
}

 对应汇编代码:

0E3B:0291 55            PUSH    BP
0E3B:0292 8BEC          MOV     BP,SP
0E3B:0294 83EC02        SUB     SP,+02
0E3B:0297 56            PUSH    SI
0E3B:0298 8D4606        LEA     AX,[BP+06]
0E3B:029B 8BF0          MOV     SI,AX
0E3B:029D 83C602        ADD     SI,+02
0E3B:02A0 8A44FE        MOV     AL,[SI-02]
0E3B:02A3 8846FF        MOV     [BP-01],AL
0E3B:02A6 B40E          MOV     AH,0E
0E3B:02A8 8A46FF        MOV     AL,[BP-01]
0E3B:02AB BB0F00        MOV     BX,000F
0E3B:02AE CD10          INT     10
0E3B:02B0 5E            POP     SI
0E3B:02B1 8BE5          MOV     SP,BP
0E3B:02B3 5D            POP     BP
0E3B:02B4 C3            RET

 

 

分享到:
评论

相关推荐

    va_start、va_end、va_list的详细使用方法

    为了解决这种需求,C语言提供了三个宏:`va_start`、`va_end`以及`va_list`,这些宏允许我们在函数中处理不定数量的参数。 #### 宏定义解析 在VC++6.0的`stdarg.h`头文件中,包含了处理可变参数列表所需的关键宏...

    stdarg.h中三个宏va_start ,va_arg和va_end的应用

    ### stdarg.h中三个宏va_start,va_arg和va_end的应用详解 在C语言中,经常需要编写能够接受可变数量参数的函数。一个典型的例子就是`printf`函数,它可以接受任意数量和类型的参数。为了支持这种功能,C语言提供了...

    详解_C语言可变参数_va_list和_vsnprintf及printf实现

    ### C语言可变参数机制详解:`va_list`与`vsnprintf`及`printf`实现 #### 引言 在C语言编程中,我们经常使用`printf`函数来输出各种格式的数据,但你是否曾思考过,这个看似简单的函数背后隐藏着怎样的复杂性?`...

    va_list(),va_start(),va_arg(),va_end() 详细解析

    写可变参数的C函数要在程序中用到以下这些宏: 代码如下:void va_start( va_list arg_ptr, prev_param );type va_arg( va_list arg_ptr, type );void va_end( va_list arg_ptr );va在这里是variable-argument(可变...

    va_arg_c_

    在C语言中,`va_arg`是一个非常重要的函数宏,它是可变参数列表(Variable Argument List,也称为 variadic function)处理的关键组成部分。标题“va_arg_c_”可能指的是一个文档,专门探讨了如何在C语言中使用`va_...

    C语言可变参数_va_list和_vsnprintf及printf实现.

    要使用`_va_list`,你需要包含`<stdarg.h>`头文件,然后利用`va_start`, `va_arg`和`va_end`宏来初始化和操作`_va_list`变量。 - `va_start`: 初始化`_va_list`变量,使其指向可变参数列表的第一个参数。 - `va_arg...

    va-list原理解释

    1. 因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能地识别不同参数的个数和类型。 2. 另外还有一个问题,因为编译器对可变参数的函数...

    关于C/C++中可变参数的详细介绍(va_list,va_start,va_arg,va_end)

    这主要通过一组预定义的宏来实现,包括`va_list`、`va_start`、`va_arg`和`va_end`,这些宏定义在`stdarg.h`头文件中。下面我们将详细探讨这些宏的用途和工作原理。 1. `va_list`: `va_list`是一个类型定义,它...

    C语言中一些可变参数的用法

    本文讨论了C语言中可变参数的用法,包括如何写一个简单的可变参数的C函数,如何使用可变参数宏va_start、va_arg和va_end,以及可变参数在编译器中的处理。 一、写一个简单的可变参数的C函数 在C语言中,某些函数...

    c语言中可变参数va宏的使用

    C语言标准库提供了处理可变参数的一系列宏,包括`va_list`、`va_start`、`va_arg`和`va_end`等。这些宏可以帮助开发者处理可变参数函数中的参数。 - **`va_list`**: 定义一个类型,用于存储指向可变参数列表的指针...

    C51可变参数讲解.pdf

    可变参数函数的实现主要包括几个宏:va_list, va_start, va_arg, va_end。下面将详细讲解这些宏以及它们的用法: 1. va_list: 这个类型用于声明一个变量,该变量会被用来遍历参数列表。在stdarg.h中,va_list被定义...

    有关va-list问题

    本文将深入探讨如何使用`va_list`、`va_start`、`va_arg`和`va_end`这四个宏来处理这种特殊的参数传递。 `va_list`是一个类型定义,它定义了一个可以存储变长参数列表中下一个参数地址的类型。在函数中,我们需要...

    C语言可变参数技术内幕.pdf

    va_start宏用于初始化可变参数表,va_arg宏用于取得当前的可变参数,va_end宏用于结束可变参数的使用。 va_start宏的原型为:void va_start(va_list ap, prev_param),其中ap是指向可变参数表的指针,prev_param是前...

    test_va_args

    2. 使用`stdarg.h`库(C)或`<cstdarg>`库(C++)处理可变参数的三个关键宏:`va_start`、`va_arg`和`va_end`。 3. 如何在函数中定义和使用`va_list`,以及如何正确处理参数类型。 4. 通过实例展示了如何创建一个...

    c语言实现的一个简单的日志函数

    这个头文件中定义了`va_list`、`va_start`、`va_arg`和`va_end`宏,它们是处理可变参数列表的关键。下面逐一解释这些宏的作用: 1. `va_list`: 这是一个类型定义,用来声明一个可变参数列表的变量。例如:`va_list ...

    C语言中可变参数的用法

    在C语言中,通过宏`va_start`、`va_arg`和`va_end`来处理这些可变参数。这些宏定义在`stdarg.h`头文件中,因此编写可变参数函数时需要包含此头文件。 #### 宏定义解析 1. **`va_start`**: 初始化可变参数列表的...

    关于可变参数va系列函数用法的几个例子

    这种机制是通过一组特殊的宏实现的,包括`va_start`、`va_arg`、`va_end`和`va_copy`。本文将详细探讨这些宏的用法,并通过几个实际例子来阐述其工作原理。 ### 一、`va_start`宏 `va_start`是用于初始化可变参数...

    C语言变参函数设计

    - **内存管理**: 避免对`va_list`指针进行不当操作,确保在使用完毕后调用`va_end`。 #### 结论 C语言的变参函数设计提供了一种灵活的方式来处理参数数量不确定的情况,尤其是在需要处理多个类型和数量不定的参数...

    c语言va函数讲解.

    C语言中的va函数,也就是可变参数函数(variable argument function),允许函数接收不定数量的参数,这种机制为函数调用提供了极大的灵活性。在C/C++标准库中,printf()和scanf()系列函数就是典型的可变参数函数,...

Global site tag (gtag.js) - Google Analytics