Как библиотечная функция (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 к ней или просто позволить потоку управления программы войти в нее, как в этом случае. (Я могу сказать, что печать не является "функцией", потому что ей не хватает правильного пролога).
Могу ли я предложить вам несколько сборочных представлений?
- http://asm.sourceforge.net/intro.html
- http://en.wikibooks.org/wiki/X86_Assembly/Introduction
- http://www.tldp.org/HOWTO/html_single/Assembly-HOWTO/
Или много других вы можете найти в Интернете
почему "формат" находится в поле.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.