汇编,多个参数-m32 / linux(与C中的stdarg相同)

时间:2013-05-05 14:28:29

标签: c assembly format arguments

为了解决这个问题,我理解C,我仍然是大会的初学者,所以我在这里遇到了一些问题。

我在使用多个参数时遇到了一些麻烦,如果我应该这样做,可能会计算它们,并在汇编代码中使用format参数。

尝试向具有多个参数的字符串添加一些字节。我知道如何将两个第一个参数放在堆栈上,但是第一个参数之后的其他参数是格式(如%s,%d,%c等),第一个参数是应该是变量i的那个想写信给。 在C中,标准main具有参数计数器。我可能想在这里算一下这些论点!?我怎么能这样做,如果这是怎么做的?

     .globl minisprintf

# Name:         minisprintf
# Synopsis:     A simplified sprintf
# C-signature:      int minisprintf(unsigned char *res, unsigned char *format, ...);
# Registers:        AL: for characters      
#                 %ECX: first argument, res
#                 %EDX: second argument, args
#



minisprintf:                    # minisprintf

    pushl       %ebp            # start of
    movl        %esp, %ebp      # function

    movl        8(%ebp), %ecx   # first argument
    movl        12(%ebp), %edx  # second argument
                                # other arguments
                                # checking last byte of string res

2 个答案:

答案 0 :(得分:1)

Variadic函数是C函数,因此最好通过查看架构/ ABI的va_startva_argva_end的开源实现方式来获得最佳效果。对此感兴趣。

对于类似printf的函数,您不需要显式参数计数,因为该信息嵌入在格式字符串中 - 期望的可变参数的数量和类型由数字和详细信息给出格式说明符。

需要了解ABI的过程调用方面是非常严肃的细节,以使所有这些正常工作。例如,浮点和整数参数是否转到同一堆栈,或者是否在寄存器中传递?您需要多大的尺寸来推广类型,以确保您的va_arg等效内容在正确的时间始终为正确的类型提供正确的选择?等等...

答案 1 :(得分:1)

我这样做的方式如下:

你已经知道前两个论点了。下一个参数将是16(%ebp),因此我将此地址放入寄存器并将其用作基址。现在我解析我的字符串,因为这给了我需要多少寄存器的信息。对于遇到的每个参数,从我的基地址获取值并将其增加4,因为下一个参数将在那里。

我认为没有必要同时将所有参数都注册,因为您可能会按顺序扫描formatstirng。