2016-12-17 14 views
-2

Я недавно начал изучать перенос из Windows в Linux. Я переводил программу из синтаксиса Intel в AT & T синтаксис, также преобразовывая его с x32 в x64. И так как я достаточно новый для ассемблера и особенно AT & T Я столкнулся с некоторыми проблемами при портировании. Просто упомянуть: я намеренно не использую директиву .intel_syntax.Портирование из Windows в Linux. Перевод команды ассемблера

Так что я получил stucked с переводом этих команд:

RTLWriteIntegerBuffer: TIMES 3 DB 0x90,0x8D,0x40,0x00 

следуют:

LEA EDI,[OFFSET RTLWriteIntegerBuffer+ECX-1] 

Еще одно:

LEA EBX,[EDX+'0'] 

еще одно:

ReadCharInited: DB 0 
CMP BYTE PTR ReadCharInited,0 

Другой вопрос: Есть ли сопоставление 1: 1 между AT & T синтаксисом и синтаксисом Intel? Или есть конкретные команды Intel, которые не поддерживаются в AT & T?

А может быть кто-то знает о функциях, как это:

HEAP_NO_SERIALIZE=1 
HEAP_GENERATE_EXCEPTIONS=4 
HEAP_ZERO_MEMORY=8 
... 
INVOKE HeapAlloc,EAX,HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY+HEAP_CREATE_ALIGN_16,4194332 

Это один, вероятно, Borland Turbo Assembler конкретным способом вызова kernel32.dll «s HeapAlloc, но я не уверен. Можно ли перевести на fallocate syscall?

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

+0

Вместо 'times' вы можете использовать' .rept' или ввести его. Для остальных читайте о синтаксисе ссылки на & t memory. 'fallocate' полностью отличается от' HeapAlloc'. – Jester

+0

Вам действительно нужен синтаксис AT & T? Не было бы намного проще переносить на газ '.intel_syntax noprefix' (который очень похож на MASM) или на синтаксис NASM? Тогда вам просто нужно будет изменить системные вызовы/ABI, а не каждую инструкцию. (См. Http://stackoverflow.com/tags/x86/info для ссылок на руководства для ассемблера) –

+2

Так легко попасть в руки вручную, что я предлагаю собирать с помощью MASM, а затем дизассемблировать с помощью 'objdump -drwC' и переносить директивы и комментарии к разборке. Я думаю, что objdump имеет возможности получить что-то ближе к тому, чтобы быть готовым к вводу ассемблера, или использовать дизассемблер objconv от Agner Fog, который делает вывод, который может быть собран снова. –

ответ

4

Говоря о «AT & T синтаксис» по сравнению с «синтаксисом Intel», он обычно относится только к разнице между мнемониками команд и порядком и форматом операндов.

Так, например, это обучение AT & T синтаксис:

movl $1, (%esi) 

и это та же команда, используя Intel синтаксис:

mov DWORD PTR [esi], 1 

Для каждой инструкции, представимых в синтаксисе Intel , есть эквивалентное представление в AT & T синтаксис для этой инструкции.

Поскольку нет ассемблера AT & T и нет ассемблера Intel больше, директивы (все, кроме инструкций) - это другое дело. Ассемблер GNU (GAS) поддерживает AT & T и синтаксис Intel, но только его собственные директивы, которые являются расширением директив, используемых ассемблером AT & T. MASM от Microsoft поддерживает только синтаксис Intel, но также и его собственные директивы, которые являются расширением оригинального сборщика Intel. Не всегда есть прямой эквивалент из директив ассемблера другому ассемблеру. В некоторых случаях тот факт, что они используют разные форматы объектных файлов, может помешать найти какой-либо способ реализации функциональности директивы в другом ассемблере, используя другой формат объектного файла. (. Или даже тот же ассемблер, используя другой формат, как может быть в случае с ассемблером GNU)

В качестве примера, вот некоторые директивы ГАЗ:

.rept 3 
.byte 0x90, 0x8D, 0x40, 0x00 
.endr 

А вот эквивалентные директивы MASM:

REPT 3 
DB 90h, 8Dh, 40h, 00h 
ENDM 

Но нет MASM эквивалента следующей директивы GAS, потому что это специфично для формата объект ELF, который MASM не поддерживает:

.protected foo 

С другой стороны, нет прямого эквивалента следующей директивы MASM, потому что ГАЗ не поддерживает сложные директивы на языке высокого уровня:

INVOKE HeapAlloc,EAX,HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY+HEAP_CREATE_ALIGN_16,4194332 

К порту бывшего ELF-специфичная директива вы бы переделать приложение, чтобы решить, как Windows обрабатывает общие библиотеки. Чтобы портировать более позднюю директиву, ориентированную на MASM, вам нужно будет создать свой собственный макрос, который выполнил бы работу по определению правильности передачи всех аргументов или просто вручную выписал все инструкции сборки, необходимые для этого вызова, в соответствии с Linux x86-64 ABI. (Вам также нужно найти подходящую функцию Linux для вызова и передачи другого набора аргументов, но это отдельная проблема при переводе самой директивы.)

Некоторые ассемблеры пытаются быть совместимыми с другими сборщиками; например, TASM Borland пытается быть совместимым с MASM, хотя это более старая версия MASM. Итак, то, что работает в TASM (в режиме MASM по умолчанию), обычно работает в MASM и наоборот. Однако многие ассемблеры используют по существу свою собственную версию ассемблера x86.

Например, код, который вы указали в своем сообщении, кажется, использует две разные версии ассемблерного языка и не может быть собран каким-либо одним ассемблером. Ваша первая строка кода использует директиву TIMES, но эта директива поддерживается только NASM, которая не использует синтаксис AT & T или синтаксис Intel. Он имеет свой собственный синтаксис команд, хотя он не отличается от синтаксиса Intel. Он также имеет свой собственный несовместимый набор директив, не основанный ни на чем, в частности, на то, что вы указали директиву TIMES.

Остальная часть вашего кода выглядит синтаксисом MASM. За исключением третьей строки, он не будет правильно собираться с NASM (и первая строка не будет правильно собрана с MASM). Я не уверен, собирался ли с TASM, так как директива INVOKE была добавлена ​​в MASM 6.

Обратите внимание, что, учитывая характер вашего кода, он, вероятно, ничего не получает, написав на ассемблере, и вы можете быть гораздо лучше перевести его на C, C++ или на другой язык, с которым вы знакомы.

+1

Я бы добавил +1 к предложению портировать на C вместо AT & T x86-64 asm с системными вызовами Linux, после того, как вы вернетесь к обсуждению директив. (Я тоже заметил TIMES и INVOKE, но не был уверен, что TIMES был только NASM). –

2

Я не очень хорошо знакомы с Windows, но позвольте мне попробовать в любом случае, чтобы помочь вам.

RTLWriteIntegerBuffer: TIMES 3 DB 0x90,0x8D,0x40,0x00 

DB директива переводит .byte в ассемблере UNIX, TIMES поддерживается в газе (как .rept), но я рекомендую, чтобы избежать его, как это не подходит для других сборщиков UNIX. Так что этот фрагмент становится

RTLWriteIntegerBuffer: 
    .byte 0x90,0x8d,0x40,0x00 
    .byte 0x90,0x8d,0x40,0x00 
    .byte 0x90,0x8d,0x40,0x00 
LEA EDI,[OFFSET RTLWriteIntegerBuffer+ECX-1] 

Операнд памяти Intel-стиль формы [disp+base+index*scale] становится в AT & T синтаксис disp(base,index,scale). Если оба index и scale пусты, вы можете написать disp(base) вместо этого, в противном случае просто оставьте отсутствующий регистр (но сохраните запятую). Ваша инструкция будет

lea RTLWriteIntegerBuffer-1(%ecx),%edi 

Обратите внимание на замененные операнды. В AT T синтаксис все коды с двумя аргументами заменяют операнды, за исключением некоторых команд с плавающей запятой.

LEA EBX,[EDX+'0'] 

Аналогичным образом, этот человек становится

lea '0'(%edx),%ebx 
ReadCharInited: DB 0 
CMP BYTE PTR ReadCharInited,0 

Этот становится

ReadCharInited: .byte 0 
    cmpb $0,ReadCharInited 

Обратите внимание на суффикс b, указывающий, что это байтовая инструкция. Другие суффиксы включают w для слова, l для (двойное долго) и q для квадраслово (только amd64). Immediates имеют префикс $, операнды памяти не имеют префиксов.

Другой вопрос: есть ли сопоставление 1: 1 между AT & T синтаксисом и синтаксисом Intel? Или существуют конкретные команды Intel, которые не поддерживаются в AT & T?

Инструкции, как правило, есть. Один из способов понять это - написать инструкцию в синтаксисе Intel, а затем сбросить ее в AT & T синтаксис (с objdump -d) или наоборот (с objdump -d -Mintel).

Для псевдоинструкций (например, TIMES или DB) может быть не так, поскольку ассемблер UNIX концептуально отличается от, например, MASM.

INVOKE HeapAlloc,EAX,HEAP_GENERATE_EXCEPTIONS+HEAP_ZERO_MEMORY+HEAP_CREATE_ALIGN_16,4194332 

Вместо этой функции, вы можете просто использовать старый добрый calloc из стандартной библиотеки C. Что-то, как это должно работать, если вы планируете связать против LIBC:

push $4194332 
push $1 
call calloc 
add $8,%esp 

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

+1

В Windows 'calloc' и' malloc' построены поверх 'HeapAlloc', а' free' построен поверх 'HeapFree', используя частную кучу, управляемую библиотекой времени C. ('HeapFree' - это противоположность' HeapAlloc', 'HeapDestroy' - это противоположность' HeapCreate'.) Итак, да, просто вызовите 'calloc' и' free' в * nix. –

2

Есть ли сопоставление 1: 1 между AT & T синтаксисом и синтаксисом Intel? Или существуют конкретные команды Intel, которые не поддерживаются в AT & T?

Оба синтаксиса могут выражать каждую форму каждой инструкции x86. Любой допустимый машинный код x86 может быть дизассемблирован либо в AT & T, MASM, либо в синтаксисе NASM.

Есть некоторые отличия, поэтому сопоставление мнемоники не точно 1: 1. Например, в синтаксисе ATT вы должны использовать movabs $0x123456789abcd, %rax, чтобы получить кодировку, использующую 64-битную немедленную.

В синтаксисе NASM ассемблер автоматически выбирает кодировку mov r64, imm64 по сравнению с кодировкой или mov r/m64, sign-extended-imm32 на основе константы. Таким образом, mov rax, 1 может собрать 5-байтовый mov r32, imm32 или 7 байт mov r/m64, imm32 (поэтому вы всегда должны писать mov eax, 1, чтобы убедиться, что вы получите меньшую кодировку). Но mov rax, 0x123456789abcd всегда будет собирать 10-байтовую форму mov r64, imm64, не используя другую мнемонику.

См. Intel's insn set ref for MOV. (Другие ссылки в теге ).

Эта архивная копия x86-64.org's what's new in x86-64 также охватывает проблему movabs vs. mov mnemonic и другие вещи.

+0

Я действительно хотел добавить для OP к этому конкретному подпункту, что AT & T против Intel отображает в основном 1: 1 (поскольку машинный код x86 - это машинный код x86, все тот же). НО, поскольку он делает также 32b -> 64b преобразование, он может столкнуться с определенными 32b инструкциями, которые более не действуют в режиме 64b, поэтому в его случае отображение 1: 1 может быть нарушено из-за 32-> 64-битного преобразования. – Ped7g

 Смежные вопросы

  • Нет связанных вопросов^_^