Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A simple C program without #include <stdio.h>

How to call "printf" directly without including stdio.h ?

I found a interesting tutorial here:
http://www.halcode.com/archives/2008/05/11/hello-world-c-and-gnu-as/

So, here's my attempt:

int main(){
 char ss[] = "hello";

 asm (
  "pushl %ebp ;"
  "movl %esp, %ebp ;"
  "subl $4, %esp ;"
  "movl $ss, (%esp) ;"
  "call _printf ;"
  "movl  $0, %eax ;"
  "leave ;"
  "ret ;"
 );

 return 0;
}

I'm using MinGW 4.4, and here's how I compile it:

gcc -c hello.c -o hello.o
ld hello.o -o hello.exe C:/mingw/lib/crt2.o C:/mingw/lib/gcc/mingw32/4.4.0/crtbegin.o C:/mingw/lib/gcc/mingw32/4.4.0/crtend.o -LC:/mingw/lib/gcc/mingw32/4.4.0 -LC:/mingw/lib -lmingw32 -lgcc -lmsvcrt -lkernel32

Unfortunately, it fails:

hello.o:hello.c:(.text+0x26): undefined reference to `ss'

How to fix this?

like image 300
anta40 Avatar asked Sep 14 '26 05:09

anta40


2 Answers

You can copy the declaration of printf into your program. In C, including other file is a mere copy-pasting its text into your program. So you can do this job by doing the copy-paste on your own.

extern int printf (const char* format, ...);

int main()
{
  printf("Hello, world!\n");
  return 0;
}

Linker will surely find the proper definition in the libraries, against which you program is linked by default.

like image 110
P Shved Avatar answered Sep 16 '26 05:09

P Shved


int main(void)
{
    char ss[] = "hello";

    __asm(
        "pushl %[ss]\n"    // push args to stack
        "call _puts\n"
        "addl $4, %%esp\n" // remove args from stack
        :: [ss] "r" (ss)   // no output args, no clobbered registers
    );

    /*  C equivalent:
        extern int puts(const char *);
        puts(ss);
    */
}
like image 33
Christoph Avatar answered Sep 16 '26 06:09

Christoph



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!