Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Ассемблер? Это просто! Учимся программировать


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Boriss
Статус: Академик
Рейтинг: 2636
∙ повысить рейтинг »
Абаянцев Юрий Леонидович aka Ayl
Статус: Профессионал
Рейтинг: 2312
∙ повысить рейтинг »
Жерар
Статус: Специалист
Рейтинг: 1722
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / Assembler (Ассемблер)

Номер выпуска:1442
Дата выхода:01.05.2011, 04:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:215 / 65
Вопросов / ответов:1 / 1

Вопрос № 182937: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Необходимо написать небольшую программу, пример: z=(x^2)-4y Осуществить ручной ввод x,y. После этого изменить цвет фона и вывести z, при этом изменив цвет шрифта. Спас...



Вопрос № 182937:

Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Необходимо написать небольшую программу, пример:
z=(x^2)-4y
Осуществить ручной ввод x,y. После этого изменить цвет фона и вывести z, при этом изменив цвет шрифта. Спасибо заранее :)

Отправлен: 25.04.2011, 17:30
Вопрос задал: JohnyWayne (Посетитель)
Всего ответов: 1
Страница вопроса »


Отвечает Лысков Игорь Витальевич (Старший модератор) :
Здравствуйте, JohnyWayne!
Чтобы использовать цвет символов, использован прямой вывод в видеопамять.
Чтобы ограничить работу с одним словом, в программе введено ограничение (полагаю, это непринципиально ):
число должно быть по модулю <= 179. (т.к. это максимальное число, когда 1792 - 4•(-179) ≤ 32767, где 32767 - максимальное знаковое число, помещающееся в слово)
Код:

.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 ;т.о., игнорируем
Digi tOk: ;все отлично, выведем введенный разряд
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

-----
Люби своего ближнего, как самого себя

Ответ отправил: Лысков Игорь Витальевич (Старший модератор)
Ответ отправлен: 26.04.2011, 15:10
Номер ответа: 266847
Украина, Кировоград
Тел.: +380957525051
ICQ # 234137952
Mail.ru-агент: igorlyskov@mail.ru

Оценка ответа: 5

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 266847 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.



    В избранное