Как библиотечная функция (C) вызывает язык ассемблера gnu?

Я компилирую код.

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

или это

.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"

почему "формат" находится в поле.text?

gcc -nostdlib file.s -o program

Почему я получаю ошибку?

/universe/earth/asm/file.s:14: неопределенная ссылка на `_printf' collect2: ld вернул 1 состояние выхода

как исправить эту ошибку?

если так, то весь код работает. Зачем???

.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"

Почему функция print: не вызывается в основном поле?

cpy: intel-64 os: debian

2 ответа

Решение

почему "формат" находится в поле.text?

.text в сборке означает "раздел кода"

gcc -nostdlib file.s -o программа Почему я получаю сообщение об ошибке? /universe/earth/asm/file.s:14: неопределенная ссылка на `_printf' collect2: ld вернул 1 состояние выхода

вы не связываете стандартные библиотеки, в которых находится printf (опция -nostdlib): компоновщик не может его найти

как исправить эту ошибку?

Либо связать стандартную библиотеку (stdlib) явно, либо связать другую библиотеку, которая обеспечивает реализацию printf, или удалите ключ -nostdlib

Почему функция print: не вызывается в основном поле?

"print" - это просто метка: вы можете вызывать ее, jmp к ней или просто позволить потоку управления программы войти в нее, как в этом случае. (Я могу сказать, что печать не является "функцией", потому что ей не хватает правильного пролога).

Могу ли я предложить вам несколько сборочных представлений?

Или много других вы можете найти в Интернете

почему "формат" находится в поле.text? Неясно, что вы спрашиваете здесь, но я думаю, что вы спрашиваете о двух вещах, сжатых здесь:

mov     $format, %rdi           # set 1st parameter (format)

format:
    .asciz  "%20ld\n"

В вашем .text раздел, вы ссылаетесь на format этикетка. Позже вы определяете format этикетка.

Почему я получаю ошибку? Вы указываете опцию компилятора -nostdlib что исключает библиотеки, которые обычно включаются, в том числе printf функция.

Почему функция print: не вызывается в основном поле? Функция печати отсутствует, но есть метка, и она используется:

jnz     print                   # if not done counting, do some more

Похоже, это точка завершения цикла, основанная на %ecx что отсчитывает от 0х90 до 0.

Другие вопросы по тегам