Я просто хочу знать, почему мы добавляем AX в SI.
В отличие от какого-то другого способа вычисления того же самого? Непонятно, о чем вы все еще удивляетесь после того, как комментарий Шута ответил на вопрос сразу. Если это не имеет смысла для вас, возможно, вам нужно начать писать код самостоятельно и / или смотреть на вывод компилятора для C, который вы понимаете, чтобы освоиться с x86 и asm, чтобы вы могли читать код других людей .
Позже JMP [SI]
отправляется к коду обработчика для этой команды, поэтому они вычисляют адрес в SI. (Он индексирует таблицу слов, поэтому добавление дважды преобразует индекс слова в смещение байта. X86-16 не имеет режимов адресации с масштабированным индексом.)
Разные заглушки обертки перед общим ENTRY
устанавливают SI
в основу разных таблиц. Очевидно, вы удалили все из них, кроме CONSOLE_INT:
из кода (вот почему есть явно бесполезный jmp short ENTRY
, который собирался бы здесь jmp +0
), но у того, который вы оставили, есть MOV SI,OFFSET CONSOLE_TABLE
.
Если бы не необходимость поддержки нескольких таблиц, они могли бы рассчитать только смещение байтов в SI или DI и использовать jmp [CONSOLE_TABLE + DI]
. Но расширение нуля до байта в SI или DI неудобно на pre-386 без MOVZX, потому что нет никаких отдельно доступных регистров верхней половины / нижней половины.
Если бы они хотели уничтожить BX, они могли бы сделать следующее, чтобы сохранить инструкцию. Но, вероятно, им нужно сохранить указатель на структуру, чтобы позже получить доступ к другим членам.
MOV bl, [BX.CMD]
xor bh, bh
add bx, bx ; word index -> byte offset
...
jmp [bx+si] ; BX can be a base register, unlike AX
Если бы они хотели сделать add ax,ax
, чтобы удвоить его до добавления к SI, они могли бы сделать CMP AL,11
раньше, до вычисления окончательного указателя, или просто сделать cmp al, 22
после удвоение AX.