Marebre8
Marebre8

Reputation: 153

x86 assembly macro for invoking a function (with arguments)

I'm trying to write a macro (in x86 assembly) that invokes a function with arguments. Variable number of arguments, that is. The functions is the first macro argument, and function arguments are 2nd-nth macro arguments.

In other words, INVOKE foo, 1, 2, 3 should expand to (stdcall convention):

push arguments

call foo

clean stack

I figured irp should do the trick, and wrote the following:

.intel_syntax noprefix
.arch i386

.data
    if: .asciz "%i\n"
.text

.macro INVOKE func, argList
    .irp arg,<argList>
    push \arg
    .endr
    call \func
    .irp arg,<argList>
    add esp, 4
    .endr
.endm

And for the test:

.globl  main
    .extern foo
main:
    INVOKE foo, 1, 5, 10, 15
    
    push eax
    push offset if
    call printf
    
    ret
.end

With a separate c file with foo:

int foo(int a, int b, int c, int d) {
    return a + b + c + d;
}

But, compiling this (using GCC) with:

gcc filename.s filename.c -o filename.out

produces the following message:

filename.s: Assembler messages:

filename.s:21: Error: too many positional arguments

Upvotes: 2

Views: 1789

Answers (1)

Jester
Jester

Reputation: 58762

The correct syntax is:

.macro INVOKE func, argList:vararg
    .irp arg, \argList
    push \arg
    .endr
    call \func
    .irp arg, \argList
    add esp, 4
    .endr
.endm

Note that arguments should be reversed for push though. Also, ideally you'd emit a single add esp only.

PS: this isn't stdcall, it's cdecl.

Upvotes: 5

Related Questions