Жаль, что вы изучаете ассемблер для микропроцессора с грязной архитектурой. Вы получаете запутанные понятия, такие как инструкция LES.
Обычный микропроцессор имеет регистры, достаточно большие, чтобы содержать полный адрес памяти. Вы можете просто загрузить адрес ячейки памяти в регистр, а затем получить доступ к этому местоположению (и обычно к тем, которые находятся рядом с индексированием) через регистр.
Некоторые машины (особенно Intel 286, которая, кажется, является тем, что вы программируете), имели только 16-битные регистры, но могли адресовать 1 МБ памяти. В этом случае регистру не хватает битов: вам нужно 20 бит, но регистры только 16 бит.
Решение состоит в том, чтобы иметь второй регистр, который содержит пропущенные биты. Простая схема состояла бы в том, чтобы потребовать 2 регистра, один из которых имел младшие 16 бит, один из которых имел старшие 16 бит, чтобы получить 32-битный адрес. Тогда инструкция, которая ссылается на два регистра, имеет смысл: вам нужно оба, чтобы получить полный адрес памяти.
Intel выбрала более сложную схему: индексный регистр (в нашем случае bx) содержит младшие 16 бит, а другой регистр (называемый ES) содержит 16 битов, которые сдвинуты влево на 4 бита и добавлены в индексный регистр, чтобы получить результирующий адрес. ES называется «сегментным» регистром, но это не имеет смысла, если вы не прочитаете о операционной системе Multics около 1968 года.
[Сегменты и сегментные регистры действительно являются интересной идеей, когда полностью реализован способ Multics. Если вы не знаете, что это такое, и у вас есть любой интерес к компьютерам и / или информационным архитекторам, найдите книгу Elliot Organick по Multics и прочитайте ее от корки до корки. Вы будете потрясены тем, что мы имели в конце 60-х годов, и, кажется, потеряли за 50 лет «прогресса».]
То, что осталось от идеи в x86, - это в значительной степени шутка, по крайней мере то, как она использовалась в «современных» операционных системах. Вам действительно все равно; когда какой-то аппаратный дизайнер представляет вам машину, вы должны жить с ней такой, какая она есть.
Для Intel 286 вам просто нужно загрузить регистр сегмента и регистр индекса, чтобы получить полный адрес. Каждое машинное обращение должно ссылаться на один индексный регистр и один сегментный регистр, чтобы сформировать полный адрес. Для Intel 286 существует 4 таких сегмента реигстера: DS, SS, ES и CS. Каждый тип инструкции явно обозначает индексный регистр и неявно выбирает один из 4 сегментных регистров, если вы не предоставите явное переопределение, в котором указано, какой из них использовать. Инструкции JMP используют CS, если вы не говорите иначе. В инструкциях MOV используется DS, если не указано иное. В инструкциях PUSH используется SS, если не указано иное (в этом случае лучше не использовать). ES - «лишний» сегмент; Вы можете использовать его только путем явного указания в инструкции (кроме инструкции перемещения блока [MOVB}, которая неявно использует как DS, так и ES).
Надеюсь, это поможет.
Лучше всего работать с более современным микропроцессором, где глупость сегментного регистра не является проблемой.