LINUX.ORG.RU

ASM ia32 -> x86_64 guide


0

0

Всем привет.

Ищу туториал, по программированию на asm под x86_64. Просто перечень основных отличий от ia32 подойдёт. Что-то я не сходу нагуглил.

★★★★

s/не сходу/сходу не/

Вечер, однако :)

Bohtvaroh ★★★★
() автор топика

Есть у интела справочники-талмуды по 3 метра в pdf: Intel 64 and IA-32 Architectures Software Developrer's Manual, Optimization Manual и иже с ними. Может сойдет.

vasily_pupkin ★★★★★
()

отличия - нет прямой адресации (вообще, делать приходится через костыль вроде mov rbx, 0+[rax]), добавлены новые регистры (8 SSE и 8 РОН), указатели исключительно 64-разрядные, добавлено несколько новых инструкций, основное - большая часть параметров в функции теперь пропихивается через регистры вместо стека (см. доку по x86_64 ABI в сырцах ядра и подобную в MSDN).

svr4
()

и одна из главных вкусняшек кроме тех, что выше написали: теперь может rip (64-битный eip) использовать %)

amoralyrr ★☆
()

> Просто перечень основных отличий

Ну, основное отличие в значении ключа -b при запуске gcc :-)

no-dashi ★★★★★
()
Ответ на: комментарий от amoralyrr

> и одна из главных вкусняшек кроме тех, что выше написали: теперь может rip (64-битный eip) использовать %)

Остальное понятно, но это зачем?

Bohtvaroh ★★★★
() автор топика
Ответ на: комментарий от svr4

> нет прямой адресации

есть
в формате инструкций IA-32 была возможность использовать абсолютную адресацию двумя способами: через SIB и без него
в IA-32e второй способ зарезервирован для rip-relative адресации, но через SIB по-прежнему абсолютная адресация работает

.code64
.text
    movq %rax, (0xAAAAAAAA) 

rei3er
()
Ответ на: комментарий от Bohtvaroh

> Остальное понятно, но это зачем?

Релоцируемый код теперь на раз можно писать.

mv ★★★★★
()

У меня проблема с вызовом функций из -lc (к примеру printf).
В дебагере вроде как функция вызывается,
но в stdout ничего не выводится. Собираю так:

as -g test.s -o test.o
ld -g -O0 --dynamic-linker=/lib/ld-linux-x86-64.so.2 -lc test.o -o test

И ещё, почему gcc передаёт аргумент в ф-ию через %edi, а не %rdi:

C-код:
void
hello ()
{
    printf ("hello\n");
}

ASM:
        movl    $.LC0, %edi
        call    puts

где .LC0 это string "hello" из .section .rodata:
.section .rodata
.LC0:
        .string "hello"

Bohtvaroh ★★★★
() автор топика
Ответ на: комментарий от Bohtvaroh

Хм, заменил

  call  printf

на

  call  puts

и всё заработало.

Bohtvaroh ★★★★
() автор топика
Ответ на: комментарий от Bohtvaroh

> И ещё, почему gcc передаёт аргумент в ф-ию через %edi, а не %rdi:

потому что адрес .LC0 < 0x100000000, а доступ к всем 64-м битам регистра требует дополнительного однобайтного префикса
при доступе к младшим 32-м битам 64-х битного регистра старшие 32 бита обнуляются

rei3er
()
Ответ на: комментарий от Bohtvaroh

> В дебагере вроде как функция вызывается,
> но в stdout ничего не выводится. Собираю так:

а ты так попробуй

.section .rodata
.LC0:
    .asciz "hello\n"

rei3er
()
Ответ на: комментарий от Bohtvaroh

> А разве .asciz не синоним .string?

может и синоним ;)
я не это хотел отметить, а '\n' в конце строки
puts() его добавляет автоматически, а printf() нет

rei3er
()
Ответ на: комментарий от rei3er

Ха, действительно помогло! Собственно всё просто, текстовый вывод буферизуется, и граница буфера - это '\n'. Необходим вызов fflush. :)

Bohtvaroh ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.