Поскольку x64 Visual Studio вообще не поддерживает встроенную сборку (последнее, что я слышал, во всяком случае), ваше лучшее независимое от компилятора решение - написать файл .asm
, который определяет функцию, назовем ее int_2d
, которая просто выдает это прерывание, а затем возвращается. Вы компилируете файл .asm
в объектный файл, связываете этот объектный файл с остальной частью вашего приложения, и затем вы можете записать extern void int_2d(void);
в заголовочный файл и вызывать его обычно из C, когда вам нужно выполнить прерывание.
Для ассемблера, который поставляется с x64 Visual Studio , файл .asm
должен выглядеть примерно так:
_TEXT segment 'CODE'
int_2d proc
xor eax,eax
int 2dh
nop
ret
int_2d endp
_TEXT ENDS
END
nop
после int 2dh
необходим, поскольку в зависимости от используемого кода операции и от того, подключен ли к процессу отладчик, обработчик INT 2D может вызывать или не вызывать один байт из код (не одна инструкция) сразу после пропуска int
инструкции. Так что вам нужно поместить туда однобайтовый NOP.
INT 2D также ожидает код операции в регистре A; известные значения этого кода операции варьируются от 0 до 5, и мне не повезло найти документацию о том, что они на самом деле делают. В примере кода произвольно выбирается значение A, равное 0. (Вам не нужно сохранять и восстанавливать его, поскольку во всех соглашениях о вызовах Windows A является закрытым при вызове.) Если вы хотите передать код операции в качестве аргумента, вы может сделать это так:
_TEXT segment 'CODE'
int_2d proc
mov eax, ecx
int 2dh
nop
ret
int_2d endp
_TEXT ENDS
END
но затем вы должны объявить функцию на стороне C как __fastcall void int_2d(uint32_t op);
(__fastcall
не нужно, но безвредно при компиляции в 64-битном режиме, я думаю.)
К сожалению, я не знаю, как написать «шаблон» (все, кроме фактических инструкций по сборке) для файла .asm
, который должен работать с максимально возможным количеством различных наборов инструментов Windows. Вышеуказанное, вероятно, не будет неприемлемым, например, для NASM.