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

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


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

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

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

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

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

Номер выпуска: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 (Россия) | Еще номера »
  • Отправить WebMoney:


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

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

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

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

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

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

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



    В избранное