Когда я тестирую встроенную сборку GCC, я использую функцию test
для отображения символа на экране с эмулятором BOCHS. Этот код работает в 32-битном защищенном режиме. Код выглядит следующим образом:
test() {
char ch = 'B';
__asm__ ("mov $0x10, %%ax\n\t"
"mov %%ax, %%es\n\t"
"movl $0xb8000, %%ebx\n\t"
"mov $0x04, %%ah\n\t"
"mov %0, %%al\n\t"
"mov %%ax, %%es: ((80 * 3 + 40) * 2)(%%ebx)\n\t"
::"r"(ch):);
}
Красный символ на экране не отображает B
правильно. Однако, когда я изменил входной регистр r
на c
следующим образом: ::"c"(ch):);
, который является последней строкой вышеуказанного кода, символ "B" отображается нормально:
Какая разница? Я получил доступ к видеопамяти через сегмент данных непосредственно после входа компьютера в защищенный режим.
Я проследил код сборки, я обнаружил, что код был собран в mov al, al
, когда выбран регистр r
, а значение ax
равно 0x0010
, поэтому al
- 0x10
. Результат должен быть таким, но почему он выбрал регистр al
. Разве он не должен выбирать регистр, который раньше не использовался? Когда я добавляю список clobbers
, я решил проблему.