Assembler x86_64 (AT&T синтаксис)

Автор osanve, 12 октября 2011, 11:54:29

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

osanve

Здравствуйте.

Идет у нас сейчас курс системного программного обеспечения. За неимением ничего другого (исключаем возможность сидеть все пары в универе, т.к. компы там тормозят ужасно), делаю лабы под линем.

Собственно в синтаксисе для 32-х разрядной системы я разобрался и проблем нет, но на свою голову решил поставить 64-х разрядную систему.

Первая лабораторная сдана, но т.к. во второй лабораторной требуется модуль из первой, то решил переводить имеющийся код под 64 разряда.

Отрывок для 32-х разрядов:
print_loop: // Начало цикла вывода массива
  pusha // Сохраняем все регистры
  pushl   (%eax)  // Кладем в стек элемент массива
  pushl   $print_format_array // Кладем в стек формат вывода ("%d ")
  call    printf // Вызываем printf (параметры функции кладутся в обратном порядке)
  addl    $8,         %esp // Выравниваем стек
  popa // Достаем из стека сохраненные регистры
  addl    $4,         %eax // Переходим к следующему элементу массива
  cmpl    $array_end, %eax // Сравниваем с адресом конца массива
  jne     print_loop // Если меньше, то переходим к выводу следуюшего элемента


В этом коде все работает нормально. А вот как я перевел на 64 разряда:
print_loop: // Начало цикла вывода массива
  pushq %rax // Сохраняем нужные регистры,
  pushq %rsi // т.к. нет поддержки инструкции pusha
  pushq %rdi
  movq  (%rax),              %rsi // Передаем число для вывода
  movq  $print_format_array, %rdi // Передаем формат вывода
  call  printf // Вызываем printf (способ передачи параметров взят из кода, полученного через gcc -S ./main.c)
  addq  $16,                 %rsp // Выравниваем стек, хотя по идее это не требуется, но и без этой инструкции не работает
  popq  %rdi // Достаем регистры из стека
  popq  %rsi
  popq  %rax
  addq  $4,                  %rax // Переходим к следующему элементу массива (массив задан как .long, что занимает 4 байта)
  cmpq  $array_end,          %rax // Сравниваем с адресом конца массива
  jne   print_loop // Если меньше, то переходим к выводу следуюшего элемента


В результате я получаю ошибку сегментации.

Что я делаю не так?

P.S. Также интересует возможность программирования псевдографики и работы мыши в консоли (желательно на примерах) на asm'е (64 разряда AT&T) или C (без плюсов, благо gcc с флагом -S рулит).

Заранее спасибо.

nezabudka

Тема конечно покрылась плесенью, но интересно было на нее наткнутся.
Мало все таки в сети ресурсов по синтаксису AT&T архитектуры x86_64. Сама
оказалась в такой же ситуации при переводе кода на 64 разрядную
систему. Думаю эту тему еще не раз откопают. Поэтому:
В x86_64 параметры при вызове библиотечных функций передаются не через
стек как в x86 а через регистры. Аргументы функции вводятся в регистры в следующем
порядке их следования.
%rdi,%rsi,%rdx,%rcx,%r8 и %r9
В %rax помещается 0
В стек записываются все последующие аргументы
идущие за номером 6.
Вместо глобальной метки _start ставится main
Компилировать программу удобнее с помощью gcc
gcc -o prog prog.s