const char instr[] = {0xC3};
typedef void(*PF)();
void main()
{
PF pf = (PF)(void*)instr;
pf();
}
Вставка машинного кода в C++
CPU_ID MACRO
db 0fh
db 0a2h
ENDM
в нормальный код Visual C++, а лучше в блок _asm {..}
Жду ответов...
Цитата:
Inline Assembler в GCC
... Он имеет формат AT&T (в противоположность обычному формату Intel). Это означает, что:
Порядок операндов изменяется на обратный
В конце команды добавляется суффикс размера: B (байт), W (слово), L (двойное слово - long). Если размер команды следует из размера операндов, то суффикс необязателен, но лучше все же его добавить
Все непосредственные значения (константы) имеют префикс '$', регистры - префикс '%'
Вот несколько примеров соответствия синтаксиса AT&T синтаксису Intel:
AT&T Intel
movl $0, %eax mov eax, 0
movl $variable, %ebx mov ebx, variable
movw variable, %ebx mov ebx, word [variable]
movb $0, (,%eax,) mov [eax], byte 0
movl %eax, $111(%ebx, %edx, 2)
mov [111 + eax + edx*2], eax
Код на ассемблере можно вставить в исходник Си с помощью команды asm(..):
asm("movw %ax, %bx");
Несколько инструкций можно разделить обычным символом новой строки ('\n'):
asm("xorl %eax, %eax \n incl %eax");
inline(#..#.....)
в Паскале. Должен же быть какой-либо эквивалент?
Цитата:
Originally posted by xm...
Нет, не то. Мне нужно вставить машинный код, т.е. прямо коды, а не инструкции ассемблера. Это должно работать как конструкция
inline(#..#.....)
в Паскале. Должен же быть какой-либо эквивалент?
Нет, не то. Мне нужно вставить машинный код, т.е. прямо коды, а не инструкции ассемблера. Это должно работать как конструкция
inline(#..#.....)
в Паскале. Должен же быть какой-либо эквивалент?
Вариант 1. Смотри _emit
Вариант 2. Создаешь байтовый массив, преобразуешь указатель на него в указатель на void(*)() функцию, вызываешь функцию по указателю:
Код:
Спасибо за помощь!
_emit (и что-то похожее на это) не declared в Visual C++ .NET, а вот в Borland C++ 3.1 существует __emit__. Но мне нужно именно в Visual C++. а по второму способу что-то не фурычит, сильно ругается...
Цитата:
Originally posted by xm...
Ещё один вопрос ;)
_emit (и что-то похожее на это) не declared в Visual C++ .NET, а вот в Borland C++ 3.1 существует __emit__. Но мне нужно именно в Visual C++. а по второму способу что-то не фурычит, сильно ругается...
Ещё один вопрос ;)
_emit (и что-то похожее на это) не declared в Visual C++ .NET, а вот в Borland C++ 3.1 существует __emit__. Но мне нужно именно в Visual C++. а по второму способу что-то не фурычит, сильно ругается...
Это достаточное для тебя доказательство :) :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_The__emit_Pseudoinstruction.asp
По поводу второго способа. Это хакинг, к нему надо подходить с ясной головой и чистыми руками.
Покажи код и расскажи на что именно ругается.
А код таков, что нужно определить тип процессора Intel, если он выше 80486, и там используется эти машинные коды 0xF и 0xA2.
что-то типа:
void is_intel()
{
char _producer[12];
_asm {
mov eax, 0
// сюда надо вставить эти байты 0xF и 0xA2
mov dword ptr _producer, ebx
mov dword ptr _producer[+4], edx
mov dword ptr _producer[+8], ecx
}
// в _producer должно получится "GeniumeIntel"
}
а во втором случае выдаёт сообщение при вызове pf(): "Unhandled exception at ....". Конечно, не исключено, что я опять что-то недопонял. Но для меня более приемлемо использование _emit. Спасибо.
Код типа
int count;
asm("movw $count, %ax");
не работает.