Search code examples
assemblyx86-64gnu-assembler

How do a library function (C) call on gnu assembly language?


I compile a code.

.data
ssttrr:
.string "%d\n"
.text
.globl main
main:
mov $213, %rdx
push %rdx
push $ssttrr
call _printf
add  $8, %rsp

or it

.global main

    .text
main:

push    %rax                    # caller-save register
push    %rcx                    # caller-save register

mov     $format, %rdi           # set 1st parameter (format)
mov     %rax, %rsi              # set 2nd parameter (current_number)
xor     %rax, %rax              # because printf is varargs
call    printf                  # printf(format, current_number)

pop     %rcx                    # restore caller-save register
pop     %rax                    # restore caller-save register

mov     %rax, %rdx              # save the current number
mov     %rbx, %rax              # next number is now current
add     %rdx, %rbx              # get the new next number
dec     %ecx                    # count down
jnz     print                   # if not done counting, do some more

pop     %rbx                    # restore rbx before returning


mov  $60, %rax
xor  %rdi, %rdi
syscall

format:
    .asciz  "%20ld\n"

why the "format" is in a .text field?

gcc -nostdlib file.s -o program

Why do I get an error?

/universe/earth/asm/file.s:14: undefined reference to `_printf' collect2: ld returned 1 exit status

how to fix this error?

if so then all the code works. Why???

.global main

    .text
main:
    push    %rbx                    # we have to save this since we use it

    mov     $90, %ecx               # ecx will countdown to 0
    xor     %rax, %rax              # rax will hold the current number
    xor     %rbx, %rbx              # rbx will hold the next number
    inc     %rbx                    # rbx is originally 1
print:
    # We need to call printf, but we are using eax, ebx, and ecx.  printf
    # may destroy eax and ecx so we will save these before the call and
    # restore them afterwards.

    push    %rax                    # caller-save register
    push    %rcx                    # caller-save register

    mov     $format, %rdi           # set 1st parameter (format)
    mov     %rax, %rsi              # set 2nd parameter (current_number)
    xor     %rax, %rax              # because printf is varargs
    call    printf                  # printf(format, current_number)

    pop     %rcx                    # restore caller-save register
    pop     %rax                    # restore caller-save register

    mov     %rax, %rdx              # save the current number
    mov     %rbx, %rax              # next number is now current
    add     %rdx, %rbx              # get the new next number
    dec     %ecx                    # count down
    jnz     print                   # if not done counting, do some more

    pop     %rbx                    # restore rbx before returning
    ret
 format:
    .asciz  "%20ld\n"

Why the function print: isn't called in main field?

cpy: intel-64 os: debian


Solution

  • why the "format" is in a .text field?

    .text in assembly means "code section"

    gcc -nostdlib file.s -o program Why do I get an error? /universe/earth/asm/file.s:14: undefined reference to `_printf' collect2: ld returned 1 exit status

    you are not linking the standard libraries, where printf is located (-nostdlib option): the linker cannot find it

    how to fix this error?

    Either link the standard library (stdlib) explicitly, or link another library that provides a printf implementation, or remove the -nostdlib switch

    Why the function print: isn't called in main field?

    "print" is just a label: you can call it, jmp to it, or just let the control flow of the program go into it, as in this case. (I can tell that print is not a "function" because it lacks a proper prologue).

    May I suggest you some assembly introductions?

    Or many others you can find on the internet