4

I want to call a print function from my C program.
assembler prog:

 #test.s
.text

    .global _start
    .global print
    .type print, @function

_start:

        call print

        # and exit.

        movl    $0,%ebx         # first argument: exit code.
        movl    $1,%eax         # system call number (sys_exit).
        int     $0x80           # call kernel.

print:
    # write our string to stdout.

        movl    $len,%edx       # third argument: message length.
        movl    $msg,%ecx       # second argument: pointer to message to write.
        movl    $1,%ebx         # first argument: file handle (stdout).
        movl    $4,%eax         # system call number (sys_write).
        int     $0x80           # call kernel.

        mov $0,   %eax
        ret
.data

msg:
        .ascii  "Hello, world!\n"      # the string to print.
        len = . - msg                  # length of the string.

I can assemble and link it using:

$as test.s -o test.o
$ld test.o -o test

And I can execute it as a program, and it outputs "Hello, world!" But when I tried to call a print from C code like this:

#include <stdio.h>
extern int print();

int main(){
    int g;
    g = print();
    printf("Hello from c!, %d\n", g);

}

It was compiled using:

$gcc -c main.c test

It just prints "Hello from c, 13", that means that the function was called and return a number of chars, but does not print anything!

What am I doing wrong?

P.S. When I trying to compile prog like this:

$as test.s -o test.o
$gcc -c main.c -o main.o
$gcc main.c test.o 

I have a error:

/usr/bin/ld: test.o: in function `_start':
(.text+0x0): multiple definition of `_start'; /usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../lib/Scrt1.o:(.text+0x0): first defined here
/usr/bin/ld: test.o: relocation R_X86_64_32 against `.data' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status
Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Mihail HRS
  • 115
  • 1
  • 1
  • 9
  • 1
    Great job in general, but I doubt sys_write() or write() actually uses printf() style formatting or looks at the additional arguments. Usually at the assembly language level one has to construct the formatted output in sections with multiple writes or build the formatted text into the data area and then write out the complete formatted buffer all at once. https://www.tutorialspoint.com/assembly_programming/assembly_system_calls.htm – clearlight Feb 22 '20 at 13:16
  • 2
    Does this help you resolve the -fPIE question? https://stackoverflow.com/questions/46123505/assembling-with-gcc-causes-weird-relocation-error-with-regards-to-data – clearlight Feb 22 '20 at 13:17
  • 1
    Compiling with `gcc -no-pie -c test.s -o test.o` and `gcc -no-pie -o main main.c test.o` seems to do the trick ... – dragosht Feb 22 '20 at 13:35
  • 2
    That's 32-bit code. Build it with `gcc -m32 main.c test.s -o main`. You can optionally use `-fno-pie -no-pie` because that's a good idea for 32-bit for efficiency. – Peter Cordes Feb 22 '20 at 15:17

1 Answers1

0

Ok, done! Thanks clearlight

I can compile all use

$as test.s -o test.o
$gcc -c main.c -o main.o
$gcc -no-pie main.c test.o 

And all will work fine!

Mihail HRS
  • 115
  • 1
  • 1
  • 9