Странное дело: Крис Касперски в своей статье http://www.insidepro.com/kk/072/072r.shtml пишет, что "Исчезла абсолютная адресация", и сассемблировать код вида Код (Text): dec byte ptr [666h] не представляется возможным под x86-64 и нужно использовать фиктивное базирование: Код (Text): xor r9, r9 dec byte ptr [r9+666h] и правда - FASM отказывается такое компилить.. НО: MASM (ml64) отлично компилит эту инструкцию! причем продизассемблировав ЕХЕшник в IDA отлично видно, что есть в х64 необходимый опкод для такой операции: Код (Text): FE 0C 25 66 06 00 00 dec byte ptr ds:666h т.о. - что получается: FASM не совсем полноценный ассемблер, если не может скомпилить подобный код? или может в FASM это как-то по-другому делается? Олег
twgt да, предложенный тобой вариант компилируется в FASM, но: FASM компилирует код "dec byte [11223344h] в: Код (Text): FE 0D 3E 33 22 11 заметь - опкод здесь FE 0D, а затем идет _относительное_ смещение на данные (относительно RIP) a MASM скомпилял код "dec byte ptr [11223344h]" в: Код (Text): FE 0C 25 44 33 22 11 видно, что опкод здесь другой - FE 0C 25, а дальше идет _абсолютный_ адрес байта. вопрос т.о. сводится к тому, как в обоих ассемблерах управлять генерацией кода (когда я хочу сам выбирать использовать ли абсолютную или относительную адресацию)?
есть ли какой-нибудь инструмент наподобие HIEW, в котором можно было бы "на лету" писать x64 код, и видеть как он выглядит в HEX? HIEW 7.40 подходит, но он платный, купить его не могу себе позволить, кряка не нашел.. IDA 5.0 64bit - не нашел возможности так делать, приходится править в ЕХЕшнике, релоадить в ИДА, и смотреть что получилось
короче, дело к ночи мыщъх тут дал маху немного... начнеём с конца: windbg -> e или a (ртфм) давай разберемся что генерирует он и что масм: масм: Код (Text): 00000000`00401001 fe0c2566060000 dec byte ptr [666h] фасм: Код (Text): 00000000`00401001 fe0d5ff6bfff dec byte ptr [00000000`00000666] заглянем в доку амд: рассмотрим ModR/M: Код (Text): Mod: 00 Code/Reg: 001 /часть опкода R/M: 100 как известно при Mod = 00 и R/M = 100b (что мы имеем в первом случае) вступает в игру SIB тут он равен 25: Код (Text): Scale: 00 Index: 100 Base: 101 ээ.. короче не углубляясь в подробности (табличка 2-3 мануала АМД) следующий дворд означает смещение с базой 0 в случае фасма он просто генерирует другой ModR/M без SIB при Код (Text): ModR/M: Mod = 00 Reg/Code = 001 /опкод R/M = 101 R/M - зарезервированное значение при котором сразу за байтом ModR/M включается displacement которое тут равно 5ff6bfff, при текущем rip = 00000000`00401001 нетрудно заметить что 666 это сумма следующей инструкции (401007) и displacement (ffbff65f): 401007 + ffbff65f = 100000666 короче я думаю что уже все врубились что команды эти делают одно и тоже но строят опкоды по разному, кстати фасм съекономил нам целый байт а вот насчёт как этим урпавлять? зачем это вам? это наверно никак разве что только свой ассемблер писать и в догонку тут на форуме пробегала тема о том что INC\DEC избегаются в связи с оптимизацией, решил просто быстренько проверить что сгенерит С: Код (Text): PUCHAR ch; ch = 0x666; *ch = *ch + 1; результат: Код (Text): mov eax,666h add byte ptr [rax],1
rain Вобщем разобрался я вроде с FASM. Действительно, в long-mode есть 2 вида адресации данных: абсолютная, и относительная (относительно rip). Причем, в отличие от x32 режима, относительная применяется по-умолчанию, т.е. если в ФАСМе написать: mov al, [11223344h], то сгенерится код относительной адресации, ссылающийся на память с постоянным смещением от этой инструкции. Это очень удобно при написании базонезависимого кода, а также полностью отпадает необходимость в relocation table в PE файлах. Единствееное ограничение - это смещение может быть максимум 32-хбитным.. т.е - невозможно скомпилять mov al, [1122334455667788h] Но в long-mode в ФАСМе можно указать также, что необходимо использовать абсолютную адресацию: mov al, [dword 11223344h] - эта инструкция не зависимо от своего положения (значения RIP) всегда занесет в al значение находящееся по абсолютному адресу 11223344h только для аккумулятора (RAX/EAX/AX/AL) возможно также указание 64-хбитного абсолютного адреса, н-р: mov eax, [qword 1122334455667788h] но не для остальных регистров: mov r9b, [qword 1122334455667788h] - ошибка компиляции.. т.о. фасм довольно гибко позволяет выбирать именно то, что хочет пользователь (абсолютная/относительная адресация) кстати, ИДА при дизассемблировании разделяет отн. и абс. адресацию с помощью указания условных cs: и ds:, хотя в long-mode оба селектора по-любому имеют базу 0. Код (Text): mov r9b, cs:11223344h - относительный адрес mov r9b, ds:11223344h - абсолютный адрес что в синтаксисе ФАСМа имеет вид: Код (Text): mov r9b, [11223344h] mov r9b, [dword 11223344h]
а у меня FASM с Код (Text): format PE64 GUI 4.0 entry start start: dec byte [ds:11223344h] сгенерировал FE 0D 3E 23 E2 10.... че за фигня? че-то не вижу тут в коде ни 11h, Ни 22h, ни 33h, ни 44h... это нормально? О_О
Necromancer13 Попробуй прибавить 10E2233E к адресу, следующему за "dec byte [ds:11223344h]" и ты получишь своё 11223344