Search
Write a publication
Pull to refresh

Comments 16

Я не готов изменять сигнатуру main(), на зато вставлю asm(" ")...

Неужели нет методов статически скомпоновать libc, оставив только puts() и exit() ?

glibc вроде как не поддерживает статическую линковку

А unsigned long используется вместо int для обеспечения соответствия размеру 64-битных регистров r__.

Если хочется гарантированно ровно 64 бита, надо юзать uint64_t.

Плюсую. А то окажется, что long всё равно 32 бита

Слишком много моделей данных (LLP64 например), что бы не использовать типы с указанием разрядности.

Если хочется гарантированно ровно 64 бита, надо юзать uint64_t.

Тот же unsigned long, но с ещё одним long.

Ну или без ещё одного long. Но то, что unsigned long - факт.

Или может есть доказательства обратного?

Мне не нужно доказывать обратное, это вам нужно найти где в спецификации языка обещают что long или long long будут ровно 64 бита длиной. Подсказка: такого там нет.

Достаточно заглянуть в файл stdint.

Ожидал, что в конце получим минималистичный файл, а вместо этого добавили ненужных секций.

Кому интересно, в скрипте линковщика можно удалить все секции кроме .text. Правда, у меня компилятор добавлял какую-то свою .note.gnu.property.

От нее избавился с помощью:

strip --remove-section=.note.gnu.property hello-data

Получилось 4505 байта (обычный hello - 15456).

То есть, на ARM это уже не скомпилировать, а упрощения эльфа сводится к заточке кода под конкретную архитектуру)

Но статья всё равно хорошая!

разве просто заменить системные вызовы на соответствующие для нужной архитектуры - не подойдёт?

Я всегда думал что системные вызовы это ОС зависимые функции, в то время как asm код является архитектурно зависимым.

Например в этой статье asm вставки соответствуют x86_64 архитектуре. То есть, на ARM компиляция должно сломаться.

Я ошибаюсь?)

На Linux для каждой архитектуры свои системные вызовы. Потому код работать будет на любой архитектуре, если знаешь правильные вызовы для этой архитектуры.

Не совсем понимаю. Допустим вот этот сниппет кода из статьи:

  asm volatile("mov $1, %%rax\n"                // номер системного вызова write (0x01)
               "mov $1, %%rdi\n"                // Файловый дескриптор stdout (0x01)
               "mov %0, %%rsi\n"                // Буфер сообщений
               "mov %1, %%rdx\n"                // Длина буфера
               "syscall"                        // Выполнение syscall
               :                                // Операндов вывода нет
               : "r"(message), "r"(length)      // Входные операнды
               : "%rax", "%rdi", "%rsi", "%rdx" // Используемые регистры

Регистры rax, rdi, rsi, rdx отсутствуют на arm архитектуре. Как в таком случае этот код скомпилируется на ARM платформе?

Касательно системных вызовов - допустим их номера совпадают на всех Linux дистрибутивах, но я не на всех unix-like осях. Уже не помню точно где читал, но на FreeBSD порядок передачи аргументов отличный от большинства Linux дистрибутивов, но при формат исполняемого файла такой-же - ELF.

Sign up to leave a comment.