Вывод мусора из программы на ассемблере x86
У меня проблема с небольшой программой на ассемблере.
Эта программа принимает ввод и преобразует его в верхний или нижний регистр. Он правильно конвертируется, но выводит мусор, и я не знаю почему.
.model small
.stack 64
.data
data1 Db 15 dup(?),'$'
data2 Db 15 dup(?),'$'
.code
start:
MOV AX, @data
MOV DS, AX
MOV SI, OFFSET data1
MOV BL, 0Dh
lop:
MOV AH, 01h
INT 21h
CMP AL, BL
JE con
MOV [SI], AL
INC SI
LOOP lop
con:
MOV SI, OFFSET data1
MOV DI, OFFSET data2
conv:
MOV AL, 60h
CMP [SI], AL
JBE lo
CMP [SI], AL
JAE co
CMP [SI], BL
JE quit
JMP quit
co:
MOV AL, [SI]
SUB AL, 20h
MOV [DI], AL
INC SI
INC DI
LOOP conv
lo:
MOV AX, [SI]
ADD AX, 20h
MOV [DI], AX
INC SI
INC DI
LOOP conv
quit:
MOV DX, OFFSET data2
MOV AH, 09h
INT 21h
MOV AH, 4Ch
INT 21h
END start
2 ответа
Тот факт, что вы выходите из этой программы с помощью функции DOS Terminate, делает невероятным, что CX будет инициализирован заранее!
Вам определенно нужно инициализировать CX=15 в начале цикла 'lop'.
Если при вводе вы нажмете ENTER, то CX будет иметь остаточное значение. Хорошо, но все еще неисправно. В противном случае CX будет действительно катастрофически 0 в начале вашей программной части con:.
Ваше преобразование основано на одном сравнении с ASCII 60h. Это неизбежно приведет к появлению мусора, когда он представлен не алфавитными символами.
Второй раз пишешь cmp [si],al
это лишнее.
Следующие jae co
только потребности ja co
,
Следующие инструкции трио никогда не выполняются.
Часть с заглавными буквами 'co:', безусловно, никогда не должна проваливаться в следующей части программы, которая по ошибке использует AX вместо AL.
Вам лучше инициализировать буфер 'data2' с 16 $ символами, потому что теперь не известно, что будет отображать DOS!
Я не сел и не попробовал программу, но обнаружил, что иногда ассемблер путается при использовании OFFSET, и замена LEA волшебным образом решит эти проблемы. Если это не сработает, значит у вас логическая ошибка, которую я просто не вижу.