1. Заголовок или название темы должно быть информативным 2. Все тексты программ должны помещаться в теги [CODE=asm] [/CODE] 3. Прежде чем задавать вопрос, см. "FAQ",если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно, такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Ассемблера. Исключение только с согласия модератора. 5. НЕ используйте форум для личного общения! Все, что не относиться к обсуждению темы - на PM! 6. Проверяйте программы перед тем, как выложить их на форум!!
1) Дан массив из 10 элементов. Вычислить разность между максимальным и минимальным элементами (используйте адресацию по базе).
2) Дан массив P[0..k]. Определить сколько элементов удовлетворяют неравенству A<P[i]<B (используйте косвенную регистровую адресацию). Я ее частчно сделал:
stac segmentstack'stack'db 128 dup ('st')
stac ends
dan segment
mass db 24,41,27,38,64,65,7,21,47,3
nmass db 10 dup(?)
A db 8,42
dan ends
cd segmentassumecs: cd, ds: dan, ss: stac
startprocfar
push ds
sub ax,ax
push ax
mov ax, dan
mov ds,ax
mov ah, 0
mov cx, 10
mov bx, offset mass
mov di, offset nmass
mov si, offset a
begin: mov al, [bx]
cmp al, [si]
jg cxz
jl s
cxz: cmp al, [si+1]
jl xz
jmp s
xz: inc ah
s: inc bxloop begin
mov [di],ahretstartendp
cd endsendstart
осталось самое сложное: Ввода с клавиатуры исходных данных и вывода на экран исходных и конечных данных. Очистить экран и вывести результат в рамке красного цвета Поменять цвет рамки через 5 сек. Помогите, пожалуйста...
Вообщем такое дело, я привел решение только второй задачи, возможно там есть что то лишнее . По поводу вопроса: такое дело: лекции нам по ассемблеру не читали, дали только методички и поставили лабы, типа на практике все и поймете... Отвечаю на вопрос (я буду цитировать из методы):
push ds - При запуске exe-программы регистр DS указывает на ее заголовок, считанной в память. Поэтому если тело программы описывается как процедура, то первой командой программы должна быть PUSH DS, которая сохраняет в стеке начальное значение DS.
ret - Выход из программы, описанной как дальняя процедура, осуществляется с помощью команды RETN или RET (типа конец процедуры).
push ax - поместить в стек нулевое смещение адреса возврата.
Мне пришлось сделать кое какое преобразование, для вводимых строк =) так как нам нужны числа [байт!], то
1. Читаем до нажатия Enter в буфер 2. Если счетчик символов в буфере больше трех - неправильный ввод 3. Если какой из символов не от 0 до 9 - неправильный ввод 4. Переводим в число, в байт.
Возможный баг - ввод числа непомещающегося в байт. Эту проверку я писать не буду =)
1. Читаем до нажатия Enter в буфер - буфер на 3 символа [Этим решается проблема 2] - используется функция MSDOS 0A
Формат буфера: 1й байт - сколько максимум символов читать [с учетом Enter] 2й байт - сколько символов введено [Без учета Enter] от 3го байта - строка символов не больше 254 байт, с завершающим 0D [Enter]
buf struc lenbuf db 4 len db 0 buf_in db 4 dup(?) ends
В Data объявляем:
simv bufs <>
В программе считываем символ:
lea dx,simv mov ah,0Ah int 21h
Все =)
2. Проблема решена на стадии планирования 1.
3. Если какой из символов не от 0 до 9 - неправильный ввод
stac segmentstack'stack'db 128 dup ('st')
stac ends
bufs struc
lenbuf db 4
len db 0
buf_in db 4 dup(?)
ends
dan segment
mass db 24,41,27,38,64,65,7,21,47,3
A db 8
B db 42
simv bufs <>
String1 db"Введите 10 чисел [Каждое число через Enter]: $"
String2 db"Введите диапазон [минимум и максимум, через Enter]: $"
String3 db"Внутри диапазона лежит $"
String4 db" чис(ла)(ел)$"
String5 db 13
db 10
db"Неправильный ввод!$"
dan ends
cd segmentassumecs: cd, ds: dan, ss: stac
; =====Процедура чтения проверки и преобразования введенного числа==========
dig:
lea dx,simv
mov ah,0Ah;читать строку
int 21h
lea si,simv+2 ;отсюда символы начинаются
xor cx,cx
mov cl,[si-1];количество символов в строке, которое введено
Check: ;проверка 0 <= введенного =< 9
cmp byteptr [si],30h; ASCII Не меньше 0?
jl @break ; меньше
cmp byteptr [si],39h;ASCII Не больше 9?
jg @break ; больше
inc si;следующий урод [извините - это из Масяни;) ]
loop Check
lea si,simv+2
xor ax,ax
mov [bx],ax
mov cl,[si-1];сколько у нас символов?
mov al,[si] ;получаем из строки символов число
sub al,30h;из строки в число
cmp cl,1
je @c1
cmp cl,2
je @c2
;домножаем на 100
shl ax,2 ;ax=ax*4
mov [bx],al
shl ax,3 ;ax=ax*8 - а в ах уже ax*4 т.е. =ax*32
add [bx],al
shl ax,1 ;ax=ax*2- а в ах уже ax*64 т.е. =ax*64
add [bx],al;4+32+64=100
xor ax,ax
inc si
mov al,[si]
sub al,30h;из строки в число
;домножаем на 10
@c2:
shl ax,1 ;ax=ax*2
add [bx],al
shl ax,2 ;ax=ax*8
add [bx],al
xor ax,ax
mov al,[si+1]
sub al,30h;из строки в число
;прибавляем остаток
@c1:
add [bx],al
mov ah,2
mov dl,0Dh
int 21h
mov dl,0Ah
int 21h
retn; ===========Выход, если не правильгый ввод====================
@break:
mov ax,0900h ; Показываем сообщение 1
mov dx,offset string5
int 21h
mov ax,4c00h
int 21h
; ==========================Начало программы====================
startprocfar
push ds
mov ax, dan
mov ds,ax; =====================================Ввод чисел====================
mov ax,0900h ; Показываем сообщение 1
mov dx,offset string1
int 21h
mov cx,10 ;10 чисел
mov bx, offset mass
xor ax,ax
vvod:
push cx;сохраняем предыдущее значение
call dig
inc bx
pop cx;восстанавливаем предыдущее значение
loop vvod
; =========================Ввод границ диапазона====================
mov ax,0900h ; Показываем сообщение 2
mov dx,offset string2
int 21h
lea bx,[A]
call dig
lea bx,[B]
call dig
; ===========================Проверка диапазона====================
xor ah, ah
mov cx, 10
mov bx, offset mass
begin: mov al, [bx]
cmp al, [A]
jg cxz
jl s
cxz: cmp al, [B]
jl xz
jmp s
xz: inc ah
s: inc bxloop begin
mov cl,ah; ================Вывод результата====================
mov ax,0900h ; Показываем сообщение 3
mov dx,offset string3
int 21h
mov dl,cl
add dl,30h
mov ah,2
int 21h
mov ax,0900h ; Показываем сообщение 4
mov dx,offset string4
int 21h
mov ax,4c00h
int 21h
startendp
cd endsendstart
Вопросы? задавай
--------------------
- Где я? - Во тьме. - В какой тьме? - Во тьме твоего мозга.