Теперь, как мне преобразовать введенное пользователем значение в десятичное и переместить его в CX.
Вы попали в ловушку забывания условий цикла, отличных от *Возможно 1006 *, с использованием инструкций, отличных от loop
.
loop
- это просто оптимизация глазка для dec cx / jnz
(без влияния на FLAGS).Используйте его только тогда, когда это самый эффективный способ зацикливания.(Или просто никогда не используйте его вообще, потому что вам все равно нужно понимать условные переходы, поэтому пропуская loop
- это на одну инструкцию меньше, чтобы узнать / запомнить. Кроме того, на большинстве современных процессоров x86, loop
намного медленнее, чемdec / jnz . Это хорошо, если вы настраиваете на реальный 8086 или оптимизируете для увеличения размера кода, хотя. Но необходимо только в качестве оптимизации .
Самый простой и логически понятный способ написания этого цикла:
MOV AH, 1 ; read a char from stdin into AL
INT 21H
mov cl, al ; ending character
mov bl, '1' ; b = current character, starting with '1'
.top: ; do {
... print CR/LF (not shown)
mov dl, bl
int 21h ; With AH=2 from printing CR/LF
inc bl ; b++
cmp bl, cl
jbe .top ; }while(b <= end_char);
Обратите внимание, что я увеличиваю после печати. Если вы увеличиваете до печати, вы будете использовать jb
для }while(b < end_char)
.
На реальном 8086, где эффективен loop
, он имеет больше инструкций и больше байтов кода внутри цикла, и, следовательно, может быть медленнее (если мы рассмотримслучай, когда издержки цикла имеют значение, а не 3х медленных системных вызовов int 21h
внутри цикла).
Но это идет вразрез с меньшим общим размером кода (из тривиальной настройки цикла). Так что это компромисс между статическимикодразмер против динамического числа команд (и количество байтов кода, которые необходимо извлечь, что было настоящей проблемой на 8086).