Когда я тестирую встроенную сборку 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, я решил проблему.
