Имея это от компилятора:
.file "b.c"
.text
.globl _start
.type _start, @function
_start:
pushq %rbp
movq %rsp, %rbp
nop
popq %rbp
ret
.size _start, .-_start
.ident "GCC: (Debian 8.3.0-6) 8.3.0"
.section .note.GNU-stack,"",@progbits
должно быть просто, но почему это sigint? (Command terminated
), когда ничего не делает программа?
Строить с
$cc -S -fno-asynchronous-unwind-tables -fno-dwarf2-cfi-asm b.c
nop
не вызывает сигнатуры. Если это в Linux, тоret
, вероятно, вызывает исключение, поскольку нет места дляret
, если вы сделали точку входа своей программы в_start
- person Michael Petch   schedule 02.06.2020void _start() { return; };
). Почему компилятор используетret
, а не что-то вроде прерывания? (чтобы избежать подписи). - person Herdsman   schedule 02.06.2020_start
особенный. Этот код C определяет_start
как обычную функцию, но затем вы связываете ее (предположительно сgcc -nostdlib foo.c
) как точку входа ELF. Не делай этого._start
должен бытьnoreturn
функцией, а также вводиться с выравниванием RSP по 16 байт, а не с выравниванием по RSP + 8 по 16 байт. - person Peter Cordes   schedule 02.06.2020_start
, а не наmain
. Если это то, что вы делаете ... компилятор GCC не знает, кто (и если что) вызвал_start
. возврат изmain
работает, когда используется библиотека C, потому что есть код запуска C, который инициализирует вещи, а затем вызываетmain
, и есть место, куда можно вернуться (код запуска C), который выполнит ожидаемое завершение. Если вы хотите, чтобы этот код завершился, вам нужно будет вызвать системный вызов выхода в конце_start
. - person Michael Petch   schedule 02.06.2020_name
идентификаторами, вы надо соблюдать правила. GCC не собирается держать вас за руку. используйте _ и __ в программах на языке C - person Peter Cordes   schedule 02.06.2020-nostdlib
, я построил его, как показано по умолчанию (то есть - с операциейret
). Я не знаю, как заставить gcc строитьnoreturn
, как вы предлагаете, но в моем случае gcc не делал этого по умолчанию - person Herdsman   schedule 02.06.2020.s
файл. Если вы запускали этот код, очевидно, вам нужно было встроить его в исполняемый файл. Если вы сделали это сas
+ld
вручную, это эквивалентноgcc -nostdlib -static
, а не построению стандартного способа для этой реализации C (где файлы реализацииcrt
.o
предоставляют_start
, который был написан вручную в asm). Чтобы функция не возвращалась, вы должны вызвать такую функцию, какexit
илиabort
, которая не возвращается. - person Peter Cordes   schedule 02.06.2020stdlib
в компиляциюas
? (не gcc). Я сделал это вручную, но компилятор as должен иметь возможность связываться с другими библиотеками (такими какstdlib
), тогда как я могу это сделать? - person Herdsman   schedule 02.06.2020as
- это просто ассемблер, а не компилятор и не компоновщик. Вы можете выполнить системный вызов выхода из встроенного asm, как показано в Компиляции без libc. Но относительно: связывание по-другому: см. Также Вызов функций C из 64-битной сборки и Связывание программы с использованием printf с ld? / Как я могу динамически связать glibc в Ubuntu а> - person Peter Cordes   schedule 02.06.2020-nostartfiles
, а не-nostdlib
, иначеundefined reference to puts'
вprintf
заявлении. Но тогда не понимаю разницы между этими двумя флагами, зачем использовать один вместо другого? - person Herdsman   schedule 02.06.2020-nostdlib
, вы не сможете вызывать какие-либо функции библиотеки C (конечно). Я не знаю, что вы пытаетесь скомпилировать; все, что вы показали, это_start
, который пыталсяret
вместоsyscall
. Если вы хотите использовать функции stdio (как правило, плохая идея от_start
), то да, вам нужна libc, но-nostartfiles
все еще может опустить код запуска CRT, который вызывает функции libc init. В GNU / Linux он может инициализироваться, если динамически скомпонован, иначе функции libc выйдут из строя. - person Peter Cordes   schedule 02.06.2020CRT startup
? Я не знаю, что это такое, кому звонит, когда звонит и зачем. Некоторые предопределенные вызовы функций мне ни о чем не говорят. Я бы хотел узнать об этом больше - person Herdsman   schedule 02.06.2020https://stackoverflow.com/questions/55314762/linking-a-program-using-printf-with-ld
, вы используете синтаксис nasm, который имеетextern printf
, но я не знаю, как сделать extern printf в газе. Кроме того, я не вижу связи с libc / glibc. В коде я вижу только ссылку на printf через extern, но при компиляции вы используете только-no-pie
и-nostartfile
, но неld file.o libc.so
, так откуда gcc знает об этом? Я бы хотел, чтобы это было написано на газу, чтобы увидеть это, вы можете это сделать? - person autistic456   schedule 04.06.2020extern
в GAS, любой неопределенный символ считаетсяextern
. Если у вас есть другой вопрос, например, как связать программу, использующуюprintf
, задайте его. (Хотя это, вероятно, дубликат одного из них: ключевым моментом являетсяgcc -no-pie -nostartfiles
, а не-nostdlib
, если вы хотите, чтобы GCC по-прежнему связывался с libc. GCC связывает libc по умолчанию, если вы не укажете ему не использовать-nostdlib
, помните, что это интерфейс для компилятор C, а также ассемблер. Используйтеgcc -v ... other options ...
, чтобы узнать, какие именно командыas
иld
он выполняет.) - person Peter Cordes   schedule 04.06.2020ld
, что-то вродеld file.o libc.so
. Я не хочу проходитьgcc
, но делаю это вручную. (as- ›ld). Итак, как ДЕЙСТВИТЕЛЬНО связать libc с газом? - person autistic456   schedule 04.06.2020as
- ассемблер, а не компоновщик. Сld
, да, просто передайте своиfile.o
и-lc
и другие необходимые параметры, например-dynamic-linker /lib64/ld-linux-x86-64.so.2
. Если вы хотите узнать, как GCC вызываетld
, запуститеgcc -v foo.s
, а затем начните пропускатьld
параметры, пока он не сломается. Тогда вы поймете, что это не было обязательным. - person Peter Cordes   schedule 04.06.2020