Author Topic: calling asm from C  (Read 9534 times)

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2565
  • Country: us
calling asm from C
« on: June 30, 2011, 04:41:47 PM »
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:
Code: [Select]
#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:
Code: [Select]
; nasm -f elf cpuvendor.asm
; nasm -f win32 --prefix _ cpuvendor.asm ???

; tell ld about us (via the .o file)
global 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

; 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!
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.


Offline MJaoune

  • Jr. Member
  • *
  • Posts: 94
Re: calling asm from C
« Reply #1 on: June 30, 2011, 04:46:43 PM »
I don't think C has easy access to the "cpuid" instruction (does it, C guys?)
No it doesn't access easily, but calling C from ASM is very useful, if you want to print something on screen you can just call the printf, without printing it from ASM which takes more time.



SMF spam blocked by CleanTalk