Хостинг портала RFpro.ru: Московский хостер Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64 РАССЫЛКИ ПОРТАЛА RFPRO.RU Лучшие эксперты данной рассылки Номер выпуска: | 1439 | Дата выхода: | 19.04.2011, 20:00 | Администратор рассылки: | Лысков Игорь Витальевич (Старший модератор) | Подписчиков / экспертов: | 215 / 66 | Вопросов / ответов: | 1 / 1 | Вопрос № 182856: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Прошу помочь составить макрос к http://rfpro.ru/question/182640 Заранее Спасибо :) ... Вопрос № 182856: Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос: Прошу помочь составить макрос к http://rfpro.ru/question/182640 Заранее Спасибо :) Отправлен: 14.04.2011, 19:25 Вопрос задал: JohnyWayne (Посетитель) Всего ответов: 1 Страница вопроса » Отвечает Лысков Игорь Витальевич (Старший модератор) : Здравствуйте, JohnyWayne! Да, пожалуйста... Например, так:
Код: ;z = x^2 / y-2, если y<2, x<0 ; = y - x, если y > x ; = -48h, в остальных случаях ;Необходимо написать программу на Ассемблере, ;которая просит ввод значений x и y, решает пример, ;и выводит ответ т.е. z.
GET_NUM MACRO STRING local CetNumStart CetNumStart: lea dx, STRING ; строка приглашения call GetNum ; введем число в AX jc CetNumStart ; повторим, если ошибка endm
CALC_Z MACRO X, Y LOCAL Cmp_Second, Set_Third, Out_Z mov ax, Y mov bx, X cmp ax, bx ;Y < X ? jle Cmp_Second ;нет -> сравниваем дальше sub ax, bx ;да -> Z = Y - X jmp Out_Z ;на вывод результата
Cmp_Second: ;вторая проверка cmp ax, 2 ;Y < 2 ? jge Set_Third ;нет -> на остальные случаи test bx, bx ;X < 0 ? jge Set_Third ;нет -> на остальные случаи
xchg ax, bx ;AX = X, BX = Y mul ax ;DX:AX = X^2 sub bx, 2 ;BX = Y - 2 cwd ;подготовимся к делению idiv bx ;AX = DX:AX / BX jmp Out_z ;на вывод
Set_Third: mov ax, -48h ;все остальные случаи
Out_Z: ;вывод результата ENDM
.model small .stack 100h .data
;строки сообщений sGetX db 0dh,0ah,'Enter X: $' sGetY db 0dh,0ah,'Enter Y: $' sOutZ db 0dh,0ah,'Z = $' sAny db 0dh,0ah,'Press any key$'
buf label byte ; буфер для приема строки с клавиатуры (по ф-и 0ah) max db 20 ; максимальная дли на строки len db 0 ; реальная длина введенной строки string db 20 dup (?) ; сама строка
.code start: mov ax, @data mov ds, ax mov es, ax
GET_NUM sGetX mov bx, ax ; сохраним в BX = X
GET_NUM sGetY
CALC_Z bx, ax
lea dx, sOutZ ; строка Z = call PrintNum ; выведем знаковое число Z
lea dx, sAny ;выведем 'Press any key' mov ah, 9 int 21h
mov ah, 0 ; ждем нажатие на клавишу int 16h
mov ax,4c00h ; конец работы int 21h
PrintNum proc ; вывод знакового числа из AX push ax mov ah, 9 int 21h ; вывод строки (из DX) pop ax
test ax, ax ;проверим на знак jns form_str ;для положительного на вывод push ax ;для отрицательного выводим - и меняем знак mov dl,'-' ;знак - mov ah, 2 int 21h 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 ; продолжим
mov ah, 2 pr_loop: ; цикл вывода десятичных цифр-символов pop dx ; востановим очередной разряд (от старшего к младшему) add dl, '0' ; символ цифры int 21h ; вывод loop pr_loop ; по всем цифрам
ret PrintNum endp ; GetNum proc ; преобразование сроки в число push bx mov ah, 9 int 21h ; приглашение ввести строку lea dx, buf mov ah, 0ah int 21h ; вводим строку
xor di, di ; здесь будем накапливать число mov cl, 0 ; флаг знака mov ch, 0 ; количество цифр xor bx, bx ; очередной знак (для сложения со словом) lea si, string ; чис ловая строка get_num_loop: lodsb ; очередная цифра ; проверим на разделители cmp al, 0dh je num_end_found ; конец ввод а cmp al, ' ' je num_end_found cmp al, 9 je num_end_found ; минус может быть олько один и в первой позиции! cmp al, '-' jne cmp_num ; на проверку цифр test ch, ch ; были ли введены цифры? jnz set_c ; были - ошибка - минус не в первой позиции! test cl, cl ; был ли уже введен минус? jnz set_c ; был - ошибка - можно только один! mov cl, 1 ; пометим отрицательное число jmp get_num_loop ; на анализ следующего символа cmp_num: cmp al, '0' ; цифра? jb set_c ; ошибка - не цифра! cmp al, '9' ja set_c
inc ch ; считаем цифры and al, 0fh ; цифра -> число (30h-39h -> 0-9) mov bl, al ; сохраним (bh=0) mov ax, 10 ; умножим на 10 imul di ; предыдущее значение test dx, dx ; больше cлова - ошибка! jnz set_c add ax, bx ; добавим сохраненный разряд jc set_c ; больше слова - ошибка! js set_c ; больше 32767 - ошибка! mov di, ax ; сохраним jmp get_num_loop ; на анализ следующего символа
num_end_found: ; встретили разделитель test ch, ch ; что-то было? jz set_c ; не было числа (например, был введен один минус) test cl, cl ; число отрицательное? jz get_num_ret neg di ; дополнительный код отрицательного числа get_num_ret: mov ax, di ; результат в ax pop bx clc ; все ок ret set_c: pop bx stc ; ошибка ret GetNum endp
end start
----- Люби своего ближнего, как самого себя Ответ отправил: Лысков Игорь Витальевич (Старший модератор) Ответ отправлен: 14.04.2011, 19:59 Номер ответа: 266706 Украина, Кировоград Тел.: +380957525051 ICQ # 234137952 Mail.ru-агент: igorlyskov@mail.ru
Оценка ответа: 5 Комментарий к оценке: Спасибо большое! Сейчас буду разбирать принципы :) Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"? | Отправить SMS #thank 266706 на номер 1151 (Россия) | Еще номера » | Оценить выпуск » Нам очень важно Ваше мнение об этом выпуске рассылки! Скажите "спасибо" эксперту, который помог Вам! Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА на короткий номер 1151 (Россия) Номер ответа и конкретный текст СМС указан внизу каждого ответа. Полный список номеров » * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов) ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются. *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании. |
Комментариев нет:
Отправить комментарий