Здравствуйте, JohnyWayne!
Чтобы использовать цвет символов, использован прямой вывод в видеопамять.
Чтобы ограничить работу с одним словом, в программе введено ограничение (полагаю, это непринципиально
):
число должно быть по модулю <= 179. (т.к. это максимальное число, когда 179
2 - 4[$149$](-179) [$8804$] 32767, где 32767 - максимальное знаковое число, помещающееся в слово)
[code h=200]
.model tiny
Attr_white_on_black equ 07h ;основной цвет (белый по черному)
Attr_yellow_on_red equ 2eh ;цвет Z (желтый по красному)
MAX_NUM equ 179 ;максимальное значение чисел X и Y
.data
x dw 0
y dw 0
sEnterX db 'Enter X: ',0
sEnterY db 'Enter Y: ',0
sZ db 'Z = ',0
sAny db 'Press any key',0
sBuffer db 16 dup (?)
.code ;сегмент кода
org 100h ;начальный адрес для СОМ-программы
start:
mov ax, 0003h ;необходимо под XP для прямого вывода в видеопамять
int 10h
mov cx, 2000h ;спрячем курсор
mov ah, 1
int 10h
mov ax, 0b800h
mov es, ax ;сегмент видеопамяти
xor di, di ;первая колонка первой строки
lea si, sEnterX ;приглашение для ввода X
call EnterNum ;введем число в AX
mov x, ax ;x = AX
mov di, 80*2 ;первая колонка второй строки
lea si, sEnterY ;приглашение для ввода Y
call EnterNum ;введем число в AX
sal ax, 1 ;умножим на 2!
sal ax, 1 ;умножим на 4!
mov y, ax ;y = AX*4
mov di, 80*2*2 ;первая колонка третьей строки
lea si, sZ ;адрес строки 'Z = '
mov ah, Attr_white_on_black ;атрибут
call PrintStr ;выведем
mov ax, x
imul x
sub ax, y ;ax = x^2 - y*4
lea si, sBuffer ;адрес буфера
call ConvertToStr ;преобразуем в строку
mov ah, Attr_yellow_on_red ;желтый по красному
lea si, sBuffer ;строка-число
call PrintStr ;выведем
mov di, 80*3*2 ;четвертая строка
lea si, sAny ;Press any key
mov ah, Attr_white_on_black ;белый по черному
call PrintStr ;выведем
mov ah, 0
int 16h ;ждем any key
mov ax, 0003h
int 10h ;чтобы очистить экран
mov ax, 4c00h
int 21h ;выход в ДОС
;вывод строки [ds:si], заканчивающейся 0, в видеопамять [es:di], аттрибут в ah
PrintStr proc
lodsb
cmp al, 0
je PrintRet ;конец строки?
stosw
jmp PrintStr
PrintRet:
ret
PrintStr endp
;ввод строки с анализом на цифры, знак минус и на переполнение
EnterNum proc
;выведем приглашение
mov ah, Attr_white_on_black ;белым по черному
call PrintStr ;выведем
xor bx, bx ;здесь будет число
mov bp, 1 ;признак знака, 1 : >0, (-1) : <0
mov cx, 10 ;будем умножать на 10
EnterLoop:
mov ah, 0 ;ждем код
int 16h
cmp al, 0dh ;Enter - выход
je EnterRet
cmp al, '-' ;минус?
jne EnterDigit ;нет - на проверку на цифру
cmp bp, 1 ;минус уже был?
jnz EnterLoop ;был - игнорируем
stosb ;выводим на экран
inc di ;со старым аттрибутом (там 07)
neg bp ;(-1) - отрицательное число
jmp EnterLoop ;вводим дальше
EnterDigit: ;проверяем на цифры
sub al, '0' ;превратим в число 0-9
jc EnterLoop ;меньше '0' - игнорируем
cmp al, 9 ;больше '9'
ja EnterLoop ; тоже игнорируем
mov ah, 0 ;делаем слово
mov si, bx ;сохраним старое слово
xchg ax, bx ;ax = старшим разрядам, bx = введенному мл разряду
imul cx ;ax = ст разр, сдвинутым на 1 десятичный разряд
add ax, bx ;сложим с младшим
cmp ax, MAX_NUM ;сравним с максимальным
jbe DigitOk ;<= - продолжаем
mov bx, si ;восстановим старое
jmp EnterLoop ;т.о., игнорируем
DigitOk: ;все отлично, выведем введенный разряд
xchg ax, bx ;ax = младшему разряду
add al, '0' ;делаем символ '0'-'9'
stosb ;выводим
inc di ;со старым аттрибутом
jmp EnterLoop ;продолжаем
EnterRet:
mov ax, bx ;введенное число
imul bp ;умножим на +-1, чтобы учесть знак
ret
EnterNum endp
;преобразование знакового числа из ax в строку [ds:si]
ConvertToStr proc
test ax, ax ;проверим на знак
jns form_str ;для положительного на вывод
push ax ;для отрицательного выводим - и меняем знак
mov al,'-' ;знак -
mov [si], al ;сохраним
inc si ;сдвигаем указатель
pop ax ;восстанавливаем число
neg ax ;меняем знак числа на +, теперь оно положительное
form_str:
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
div_loop: ;цикл получения десятичных разрядов
xor dx, dx ;подготовимся для очередного деления
div bx ;в dx остаток - очередной десятичный разряд
push dx ;сохраним в стеке (от младшего к старшему)
inc cx ;посчитаем
test ax, ax ;есть еще десятичные разряды?
jnz div_loop ;продолжим
pr_loop: ;цикл вывода десятичных цифр-символов
pop ax ;востановим очередной разряд (от старшего к младшему)
add al, '0' ; символ цифры
mov [si], al ;сохраняем
inc si
loop pr_loop ; по всем цифрам
mov byte ptr [si],0 ;закроем строку 0
ret
ConvertToStr endp
end start
[/code]