2

I want to call at least 1 C function from assembly. It is because I'm doing my own tiny OS from scratch(out of nothing). The reason i want to call c function from my boot loader. I can understand assembly but poor in writing my own program. So if i could transfer control from assembly procedure to c procedure my job is made easier.

So how to link assembly pgm and C program files into one. It is ok for me even if the file size exceeds 512 bytes. I am doing this on Windows 7 with help of mingw. my c compiler is gcc and assembler is nasm.

manuhg
  • 360
  • 1
  • 4
  • 16
  • 4
    Check [this tutorial](http://wiki.osdev.org/Bare_Bones) and see `call kmain`. You have to implement the correct C calling convention in the assembler. – Kerrek SB Jan 14 '12 at 15:08

1 Answers1

2

easier to just show you an example, I found this on the internet a while ago and saved it as a source on my computer, not sure where from though

; printf1.asm   print an integer from storage and from a register
; Assemble: nasm -f elf -l printf.lst  printf1.asm
; Link:     gcc -o printf1  printf1.o
; Run:      printf1
; Output:   a=5, eax=7

; Equivalent C code
; /* printf1.c  print an int and an expression */
; #include 
; int main()
; {
;   int a=5;
;   printf("a=%d, eax=%d\n", a, a+2);
;   return 0;
; }

; Declare some external functions
;
        extern  printf      ; the C function, to be called

        SECTION .data       ; Data section, initialized variables

        a:  dd  5       ; int a=5;
fmt:    db "a=%d, eax=%d", 10, 0 ; The printf format, "\n",'0'


        SECTION .text                   ; Code section.

        global main     ; the standard gcc entry point
main:           ; the program label for the entry point
    push    ebp     ; set up stack frame
    mov     ebp,esp
    mov eax, [a]    ; put a from store into register
    add eax, 2      ; a+2
    push    eax     ; value of a+2
    push    dword [a]   ; value of variable a
    push    dword fmt   ; address of ctrl string
    call    printf      ; Call C function
    add     esp, 12     ; pop stack 3 push times 4 bytes

    mov     esp, ebp    ; takedown stack frame
    pop     ebp     ; same as "leave" op

mov eax,0       ;  normal, no error, return value
ret         ; return
Code Bundle
  • 282
  • 1
  • 2
  • 14
  • http://www.csee.umbc.edu/portal/help/nasm/sample.shtml#printf1 found where I got it. – Code Bundle Sep 08 '12 at 15:08
  • I am getting `/usr/bin/ld: test2.o: relocation R_X86_64_PC32 against symbol 'puts@@GLIBC_2.2.5' can not be used when making a PIE object; recompile with -fPIE /usr/bin/ld: final link failed: bad value collect2: error: ld returned 1 exit status` error when tried to call puts. – Sourav Kannantha B Mar 06 '21 at 09:18
  • Solved.. Had to use -no-pie when creating executable. – Sourav Kannantha B Mar 06 '21 at 09:53
  • @SouravKannanthaB: See [Can't call C standard library function on 64-bit Linux from assembly (yasm) code](https://stackoverflow.com/a/52131094) re: calling libc functions in PIE executables, GCC's default in modern distros. (The answer you're commenting under is 32-bit code which wouldn't assemble in 64-bit mode anyway, but the `extern foo` / `call foo` part is the same in both modes.) – Peter Cordes Aug 26 '21 at 01:05