Консультация № 180141
03.10.2010, 19:43
0.00 руб.
0 1 1
Здравствуй те Эксперты, Помогите пожалуйста.
1.Процессор х86 /Консольное приложение
2. Для Dos/Windows Xp sp3 ( обычное приложение консольное )
3. Tasm
4. -
5. Размер по типу dw, знаковый.
Теперь насчет по заданию.
Само задание написать программу для нахождение уравнения по типу y=y1*y2. где y1 =3+x если х=a, либо a-x если x<>a; y2= |a| если a<x , либо |a|-x если a>=x;
В задаче использовать стандартный поток ввода и вывода = 0ah 21h (ввод) и 09ah 21h (вывод) Обращение к клавиатуре не нужно.
и ограничение на использование команд можно loop,lea. разрешено использовать циклы, метки, использование лишь знаковых условий.
если покороче то на уровне 2 курса 1 семестра на начале)
и у меня вопрос такой - у меня есть код примерный, но я не могу в нем разобраться.
по коду у меня возникают вопросы, во первых куда у нас заносятся значения? как их вытащить ? и можно ли занести значения в y1,y2,y?
еще я немогу понять вот строчка jmp prog1, получается мы символ а не вводим, хотя он нужен.


Приложение:
data segment
msg1 db 'Enter x: $', 0Dh, 0Ah
msg2 db 0Ah,'Enter a: $', 0Dh, 0Ah
buf db 6, 0, 6 dup(?)
x dw 0
a dw 0
y1 dw 0
y2 dw 0
y dw 0
data ends
s segment stack
db 128 dup(?)
s ends
assume cs: code, ds: data, ss: s
code segment
start:
mov ax, data
mov ds, ax
inputx: ;вывод сообщения 1
lea dx, msg1
mov ah, 09h
int 21h
lea dx, buf ;ввод строчки в буфер
mov ah, 0Ah
int 21h
jmp prog1
inputa:
lea dx, msg2 ;вывод сообщения 2
mov ah, 09h
int 21h
lea dx, buf ;ввод строчки в буфер
mov ah, 0Ah
int 21h
prog1:
mov cl, [buf+1]
lea si, buf+2
cmp byte ptr [si], "-" ;проверяем есть ли минусик
jnz plus
dec cl если есть отнимаем от количества введенных цифр единичку
inc si и переходим на следующую циферку
метка plus стоит после всех этих кодов "для справки"..

Обсуждение

давно
Посетитель
7438
7205
07.10.2010, 04:31
общий
это ответ
Здравствуйте, Константин Васерман.

"если покороче то на уровне 2 курса 1 семестра на начале)" - сложно вспомнить, что было 28 лет назад

"и у меня вопрос такой - у меня есть код примерный, но я не могу в нем разобраться." - указанный Вами код приведен не полностью

"еще я немогу понять вот строчка jmp prog1, получается мы символ а не вводим, хотя он нужен." - совершенно верно, явная ошибка

Посмотрите мою программу, думаю разберетесь
Некоторые последовательности действий оформил в виде подпрограмм.
Надеюсь, это будет "на уровне 2 курса 1 семестра на начале"?

Если что не понятно, можете спросить в мини-форуме

Код:

data segment
msg1 db 'Enter x: $', 0Dh, 0Ah
msg2 db 0Ah,'Enter a: $', 0Dh, 0Ah
msg3 db 0ah,'y = ' ;сообщение о результате
num3 db ' ','$' ;адрес младшей цифры, будем строить в обратном порядке
buf db 6, 0, 6 dup(?)
x dw 0
a dw 0
;y1 dw 0 ;данные переменные, по сути, не нужны
;y2 dw 0 ;т.к. для хранения будем использовать y и регистр ax
y dw 0
data ends

s segment stack
dw 128 dup(?) ;стек принято считать состоящим из слов, а не байт
s ends

assume cs: code, ds: data, ss: s
code segment
start:
mov ax, data
mov ds, ax
;Введем х
lea dx, msg1 ;сообщение
call InputNum ;вводим число, результат в ax
mov x, ax ;сохраним в x
;Введем а
lea dx, msg2 ;сообщение
call InputNum ;вводим число, результат в ax
mov a, ax ;сохраним в а

;считаем y=y1*y2.

;считаем y1 =3+x если х=a, либо a-x если x<>a;
call CalcY1 ;результат в ax
mov y, ax ;y=y1=ax

;считаем y2= |a| если a<x , либо |a|-x если a>=x;
call CalcY2 ;результат в ax
imul y ;ax=ax*y (y=y2*y1, ax=y2, y=y1)
; mov y, ax ;сохранение излишне, будем выводить прямо из ax

call Output ;выведем результат

mov ax, 4c00h ;выход в ДОС
int 21h

;Подпрограмма ввода знакового числа
;на входе dx = адресу строки приглашения
;на выходе ax = введенному числу
InputNum proc
mov ah, 09h ;выведем приглашение
int 21h
lea dx, buf ;ввод строчки в буфер
mov ah, 0Ah
int 21h

;преобразуем строку в число
xor bx, bx ;здесь будем формировать число
xor bp, bp ;знак числа (0=+, 1=-)
xor cx, cx ;счетчик цифр, чтобы использовать слово, сначала обнулим его
mov cl, [buf+1] ;счетчик введенных символов
jcxz InputNumRet ;проверим на пустую строку
lea si, buf+2 ;адрес собственно введенной строки
mov di, 10 ;будем умножать на 10
cmp byte ptr [si], "-" ;проверяем есть ли минусик
jnz plus ;нет минуса - число >= 0
dec cx ;если есть отнимаем от количества введенных цифр единичку
inc si ;и переходим на следующий символ
inc bp ;имеем отрицательное число
jcxz InputNumRet ;проверим еще раз на количество символов
plus: ;цикл ввода цифр
lodsb ;вводим очередной символ
cmp al, '0' ;проверим на цифру
jl next ;нецифру пропустим
cmp al, '9'
jg next
xchg ax, bx ;bx - введенный символ, ax - старшие разряды числа
imul di ;умножим старшие разряды на 10
xchg ax, bx ;bx - старшие разряды числа * 10, ax - младший разряд
and ax, 0fh ;превратим символ '0'-'9' в число 0-9
add bx, ax ;добавим младший разряд к старшим
next:
loop plus ;на следующий символ

mov ax, bx ;результат в ax
test bp, bp ;проверим знак
jz InputNumRet ;положительное число - на выход
neg ax ;отрицательное - меняем знак
InputNumRet:
ret
InputNum endp

;y1 =3+x если х=a, либо a-x если x<>a;
CalcY1 proc
mov ax, a
cmp ax, x ;сравним а и х
je CalcY1_1
CalcY1_2: ;a <> x
sub ax, x ;y1 = ax = a - x
jmp CalcY1_ret
CalcY1_1: ;a = x
mov ax, x ;y1 = ax = x
add ax, 3 ;y1 = ax = x + 3
CalcY1_ret:
ret
CalcY1 endp

;y2= |a| если a<x , либо |a|-x если a>=x;
CalcY2 proc
mov ax, a ;ax = a
cmp ax, x ;сравним а и х
jl CalcY2_1
CalcY2_2: ;a >= x
call CalcModul ;ax = |ax| = |a|
sub ax, x ;y2 = ax = |a| - x
jmp CalcY2_ret
CalcY2_1:
call CalcModul ;y2 = |ax| = |a|
CalcY2_ret:
ret
CalcY2 endp

;модуль содержимого ax
CalcModul proc
test ax, ax ;проверим ax на знак
jge CalcModul_ret ;если ax >= 0, то на ничего не делаем
neg ax ;отрицательное - меняем знак
CalcModul_ret:
ret
CalcModul endp

;вывод результата из ax
Output proc
lea di, num3 ;адрес последней цифры результата
xor bp, bp ;знак числа
mov bx, 10 ;будем делить на 10
test ax, ax ;проверим на знак
jge Output_positive ;для >= 0 сразу идем на вывод
inc bp ;помечаем отрицательное число
neg ax ;делаем положительным
Output_positive: ;цикл формирования цифр
xor dx, dx ;подготавливаем деление
idiv bx ;dx:ax / 10
or dl, '0' ;остаток dl+'0' - очередная младшая цифра
mov [di], dl ;сохраняем
dec di ;сдвигаемся к более старшему разряду
test ax, ax ;проверим, есть ли еще
jnz Output_positive ;продолжаем
; осталось только учесть знак
test bp, bp ;проверим флаг
jz Output_num ;положительное - на выход
mov byte ptr [di], '-' ;для отрицательного выведем '-'
Output_num: ;числовая строка сформирована
lea dx, msg3 ;осталось только вывести
mov ah, 9
int 21h
ret
Output endp

code ends
end start
5
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа