Программа сборки 8086 всегда печатает одну и ту же строку
Я написал следующую программу, используя emu8086 с включенным синтаксисом fasm. Как вы можете видеть, программа должна напечатать "Флаг переполнения не установлен" в первый раз, а затем после добавления устанавливает флаг переполнения, затем она должна вывести "Флаг переполнения не установлен".
Однако это не то, что происходит. Программа вместо этого печатает "установленный флаг переполнения" в любом случае. Я прошел этот код, и o_set находится по адресу 0, o_notset по адресу 13h. Независимо от того, помещены ли 13h или 0h в dx в то время, когда вызывается int 21h с al 09h, он печатает "установленный флаг переполнения". Я запутался здесь, потому что фактически назначаю их как две отдельные области в сегменте данных. Обратите внимание, что логика перехода работает нормально, проблема в том, что независимо от того, что находится в dx, всегда печатается одно и то же сообщение. На самом деле, если я помещаю 99 внутри dx, он все равно печатает "установленный флаг переполнения".
format MZ
entry code_seg:start
stack 256
segment data_seg
o_set db "Overflow flag set $"
o_notset db "Overflow flag not set $"
segment code_seg
start:
push bp
mov bp, sp
mov cl, 99
jo of_flag_set
push o_notset
call printf
add sp, 2
add cl, 98
jo of_flag_set
jmp endme
of_flag_set:
push o_notset
call printf
add sp, 2
endme:
mov sp, bp
pop bp
mov ah, 0h
int 20h
; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
printf:
push bp
mov bp, sp
mov dx, [bp+4] ;cant pop the retn addr into dx
mov ah, 09h
int 21h
mov sp, bp
pop bp
ret
1 ответ
Я прокомментировал вещи, которые были неправильными и нуждались в исправлении:
format MZ
entry code_seg:start
stack 256
segment data_seg
; Add carriage reurn and line feed to ut output on seprate lines.
o_set db "Overflow flag set", 13, 10, "$"
o_notset db "Overflow flag not set", 13, 10, "$"
segment code_seg
start:
push bp
mov bp, sp
mov ax, data_seg ; We must set up the DS register by pointing
; at the segment with our data
mov ds, ax
test ax, ax ; Make sure overflow flag is cleared
; Not guaranteed when our program starts
mov cl, 99
jo of_flag_set ; You jumped to the wrong label when overflow was set
push o_notset
call printf
add sp, 2
add cl, 98
jo of_flag_set
jmp endme
of_flag_set:
push o_set
call printf
add sp, 2
endme:
mov sp, bp
pop bp
mov ah, 0h
int 20h
; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
printf:
push bp
mov bp, sp
mov dx, [bp+4] ;cant pop the retn addr into dx
mov ah, 09h
int 21h
mov sp, bp
pop bp
ret
Ваша строка не печаталась должным образом (они были смещены на экране), потому что вы не настроили регистр DS (сегмент данных). При создании программ DOS MZ (EXE) вам необходимо явно перемещать местоположение сегмента вашей области данных data_seg
в DS. Поскольку вы этого не делали, ваши строки печатались не в тех местах.
Я добавил возврат каретки и перевод строки в ваши строки, чтобы они печатались на отдельных строках.
Ваш код не может полагаться на сброс флага переполнения при запуске программы. Вам нужно использовать инструкцию, которая очистит его. test ax, ax
сделает свое дело, если вы не возражаете против изменения других флагов.
Была ошибка в одном из ваших jo
инструкции, где он указывал на неправильную метку при обнаружении переполнения.