3.2.2. Синтаксис AT&T |
Вверх Предыдущий Следующий |
В ранних версиях Free Pascal использовал только GNU в качестве ассемблера при генерации объектных файлов для процессоров Intel x86. только спустя некоторое время был создан встроенный ассемблер, который непосредственно создаёт объектный файл. Так как ассемблер GNU использует синтаксис AT&T, написанный вами код должен использовать этот же синтаксис. Отличия между синтаксисом AT&T и Intel, который используется в Turbo Pascal, приведены ниже: •Имя кода операции включает в себя размер операнда. В общем, можно сказать, что имя кода операции AT&T является именем кода операции Intel с суффиксом l, w или b для, соответственно, типов longint (32 бита), word (16 бит) и byte (8 бит) памяти или регистров. Например, конструкция Intel mov al, bl эквивалентна инструкции стиля AT&T movb %bl,%al. •В AT&T непосредственные операнды обозначаются с $, в то время как в синтаксисе Intel не используется префикс для таких операндов. Таким образом, конструкция Intel mov ax, 2 становится movb $2, %al в синтаксисе AT&T. •В AT&T имена регистров начинаются с префикса %. Этого нет в синтаксисе Intel. •В AT&T абсолютные операнды jump/call обозначаются знаком *, синтаксис Intel не разграничивает эти адреса. •Порядок следования операндов источника и приёмника меняются местами. Синтаксис AT&T использует Источник, Приёмник, в то время как синтаксис Intel использует Приёмник, Источник. То есть конструкция Intel add eax, 4 трансформируется в addl $4, %eax на диалекте AT&T. •Непосредственные длинные переходы сопровождаются префиксом l. То есть конструкция Intel call/jmp section:offset трансформируется в lcall/ljmp $section,$offset. Аналогично для дальних возвратов – lret вместо ret far на Intel. •Ссылки на память определяются по разному в ассемблерах AT&T и Intel. Косвенная ссылка на память в Intel: Section:[Base + Index*Scale + Offs] В синтаксисе AT&T будет как: Section:Offs(Base,Index,Scale) где Base и Index являются не обязательными 32-разрядными регистрами базы и индекса, а Scale используется как множитель для Index. Он может принимать значения 1, 2, 4 и 8. Section используется для указания дополнительного регистра для операнда памяти. Больше информации о синтаксисе AT&T можно найти в руководстве, хотя нужно принять во внимание следующие отличия от обычного ассемблера AT&T: •Поддерживаются только следующие директивы: .byte .word .long .ascii .asciz .globl •Следующие директивы распознаются, но не поддерживаются: .align .lcomm В будущем они будут поддерживаться. •Директивы чувствительны к регистру, остальные идентификаторы НЕ чувствительны к регистру. •В отличие от gas, локальные метки/идентификаторы должны начинаться с .L. •Оператор ! не поддерживается. •Строковые выражения в операндах не поддерживаются. •CBTW, CWTL, CWTD и CLTD не поддерживаются, используйте вместо них обычные эквиваленты Intel. •Выражения с константами, которые представляют ссылки на память, не допускаются, даже если непосредственно значение константы поддерживается. Пример: const myid = 10; … movl $myid,%eax -- допускаетсяmovl myid(%esi),%eax – НЕ допускается. •Если найдена директива .globl, то идентификатор, следующий непосредственно за ней, становится общедоступным и сразу же выделяется. Поэтому имена меток с этим именем будут игнорироваться. •Только коды операций Single и Double FPU поддерживаются. Встроенный ассемблер AT&T поддерживает следующие макросы: __RESULT представляет результат работы функции и возвращает значение. __SELF представляет указатель на метод объекта в методах. __OLDEBP представляет старый указатель базы в рекурсивных процедурах. |