Haim
Haim

Reputation: 77

Write a fopen function in assembly

I am trying to implement fopen in turbo c++ 3.0, I need to write it in asm inline.

I wrote a code, but (no suprise....) it's not working (compilation failed).

The code is here:

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <stdlib.h>

int my_fopen_w(char fname[])
{
    int fd;
    char status;
    status = 'w'; // I need to write to a file and delete previous content
    asm{
        mov bl, status
        xor bh,bh
        push bp
        mov bp, sp
        push bx
        push fname
        //Same as fopen now fopen(file path= fname, "w" = bx)
        call _fopen
        add sp,8

        // Returned value in AX register 
        mov fd, ax  // That line may be incorrect, my teacher demands an Integer returned value  

    }
    return fd;
}

I got an error: turbo c does not recognize _fopen call.

Error with "call _fopen"

Error with "call fopen" Thanks for any help.

Haim

Upvotes: 3

Views: 3054

Answers (1)

rkhb
rkhb

Reputation: 14409

This seems to be a bug in Turbo C 3.0. TCC 3.0 by default links the C library into the CODE segment, so you can load AX with the address of the C function (you don't need the underscore) and then use CALL AX:

#include <stdio.h>

int main ( void )
{
    char fname[] = "noname.txt";
    char status[] = "wb";
    FILE * fd;
    asm{
        lea ax, status
        push ax
        lea ax, fname
        push ax

        lea ax, fopen
        call ax

        pop cx
        pop cx
        mov fd, ax
    }
    return 0;
}

Please note: fopen needs two pointers to two strings. Both pointers are unknown at compile time. So you have to use LEA to get them at run time, except somebody else (operating system, C startup code etc.) has got the pointer for you:

#include <stdio.h>

FILE*  my_fopen_w(char fname[])
{
    FILE * fd;
    char  status[]="wt";
    int my_fd;

    asm{
        lea ax, status
        push ax
        mov ax, fname               // fname was passed as a pointer ("Call by value")
        push ax

        lea ax, fopen
        call ax

        pop cx
        pop cx
        mov fd, ax
    }
    return fd;
}

int main(int argc, char *argv[])
{

  FILE * fd;

  fd = my_fopen_w(argv[1]);         // argv[1] is a pointer to a string
  fputs("Here I am.", fd);
  fclose(fd);

  return 0;

}

Upvotes: 2

Related Questions