В чем разница между сборкой на Mac и сборкой на Linux?

Я пытался познакомиться с сборкой на Mac, и из того, что я могу сказать, документация действительно разрежена, и большинство книг на эту тему предназначены для Windows или Linux. Я думал, что смогу перевести с linux на mac довольно легко, однако это (linux)

.file   "simple.c"
.text
.globl simple
.type   simple, @function
simple:
      pushl   %ebp
      movl    %esp, %ebp
      movl    8(%ebp), %edx
      movl    12(%ebp), %eax
      addl    (%edx), %eax
      movl    %eax, (%edx)
      popl    %ebp
      ret
.size   simple, .-simple
.ident  "GCC: (Ubuntu 4.3.2-1ubuntu11) 4.3.2"
.section        .note.GNU-stack,"",@progbits

кажется довольно отличным от этого (mac)

.section    __TEXT,__text,regular,pure_instructions
.globl  _simple
.align  4, 0x90
_simple:                                ## @simple
    .cfi_startproc
## BB#0:
pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    addl    (%rdi), %esi
    movl    %esi, (%rdi)
    movl    %esi, %eax
    popq    %rbp
    ret
    .cfi_endproc


.subsections_via_symbols

"Нормальные" (из-за отсутствия лучшего слова) инструкции и регистры, такие как pushq %rbp, не волнуют меня. Но "странные", такие как .cfi_startproc и Ltmp2:, которые представляют собой smack dab в середине машинных команд, не имеют никакого смысла.

Я не знаю, куда пойти, чтобы узнать, что это такое и что они означают. Я собираюсь вытащить свои волосы, поскольку я пытался найти хороший ресурс для начинающих в течение нескольких месяцев. Любые предложения?

Ответ 1

Во-первых, вы сравниваете 32-разрядную сборку x86 с 64-разрядным x86-64. Хотя OS X Mach-O ABI поддерживает 32-разрядный IA32, я подозреваю, что вы хотите x86-64 SysV ABI. (К счастью, сайт x86-64.org, похоже, снова поднят). Модель Mach-O x86-64 по существу является вариантом ELF/SysV ABI, поэтому различия относительно незначительны для кода пользовательского пространства, даже с разными сборщиками.

Директивами .cfi являются DWARF директивы отладки, которые вам не нужны строго для сборки, - они используются для информации о кадре вызова и т.д. Вот некоторые минимальные примеры:

Ассемблер ELF x64-64:

    .text
    .p2align 4

    .globl  my_function
    .type   my_function,@function

my_function:
    ...
.L__some_address:

    .size    my_function,[.-my_function]

Ассемблер Mach-O x86-64:

    .text
    .p2align 4

    .globl  _my_function

_my_function:
    ...
L__some_address:

За исключением написания учебника asm, основными отличиями между сборщиками являются: подчеркивание символов для имен функций Mach-O, .L vs L для ярлыков (адресатов). Ассемблер с OS X понимает директиву ".p2align". .align 4, 0x90 по существу делает то же самое.

Не все директивы в коде, сгенерированном компилятором, необходимы для того, чтобы ассемблер генерировал действительный объектный код. Они необходимы для генерации кадров стека (отладки) и обработки исключений. Для получения дополнительной информации см. Ссылки.

Ответ 2

Очевидно, что код Linux - это 32-разрядный код Linux. Обратите внимание, что 64-разрядная Linux может запускать как 32-, так и 64-битный код!

Код Mac - это, безусловно, 64-разрядный код.

Это основное отличие.

Строки ".cfi_xxx" - это только информация, используемая для формата файла Mac.