Calling C functions from asm is fun, but not that useful - could have done it all in C! Calling some asm function - something C won't do easily - from a "C main" might be more useful. I don't think C has easy access to the "cpuid" instruction (does it, C guys?), so that might make an example...
The C code:
#include <stdio.h>
int cpu_vendor(char *dest);
int main(){
char buf[13];
int cpuid_max_level;
cpuid_max_level = cpu_vendor(buf);
printf("vendor = %s\nmaxlevel = %d\n", buf, cpuid_max_level);
return (0);
};
And the asm code:
; nasm -f elf cpuvendor.asm
; nasm -f win32 --prefix _ cpuvendor.asm ???
; tell ld about us (via the .o file)
global cpu_vendor
cpu_vendor:
; C expects to have these regs preserved
push edi
push ebx
; our parameter, the buffer, is "up the stack",
; 4 for ebx, 4 for edi, 4 for return address = 12
mov edi, [esp + 12]
xor eax, eax
cpuid
; with eax = 0, cpuid returns the vendor string
; in ebx, edx, ecx (why???), and the maximum level
; in eax (our return value). With eax greater than
; this maximum level (for this implementation of cpuid)
; cpuid returns unexpected results - 16 cores in this
; clunker? I don't think so!
; stuff the vendor string into our destination buffer
mov [edi], ebx
mov [edi + 4], edx
mov [edi + 8], ecx
; don't forget to zero-terminate it!
mov byte [edi + 12], 0
; restore caller's regs
pop ebx
pop edi
; we're done!
ret
As usual, I haven't tested this in Windows. "Should" work - if it doesn't, holler and we'll see if we can figure out why not.
Best,
Frank