1) Дан массив из 10 элементов. Вычислить разность между максимальным и минимальным элементами (используйте адресацию по базе).
2) Дан массив P[0..k]. Определить сколько элементов удовлетворяют неравенству A<P[i]<B (используйте косвенную регистровую адресацию). Я ее частчно сделал:
stac segment stack '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 segment assume cs: cd, ds: dan, ss: stac
start proc far 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 bx loop begin mov [di],ah ret start endp cd ends end start
осталось самое сложное: Ввода с клавиатуры исходных данных и вывода на экран исходных и конечных данных. Очистить экран и вывести результат в рамке красного цвета Поменять цвет рамки через 5 сек. Помогите, пожалуйста...
Dark
21.12.2004 8:18
Извини, но начну я с комертария =)
Я разбил задачи на два модуля [похоже ты хотел все сделать в одном]
Код
mass db 24,41,27,38,64,65,7,21,47,3
- Это для втророй задачки, насколько я понял =)
A db 8,42
- Поскольку, как я понял, эти 2 числа вводяться с клавы, лучше их разбить на 2 переменные, т.е.
A db 8 B db 42
nmass db 10 dup(?) - необходимость этого я так и не увидел, тока как для первой задачи.
Добавил строки вывода в начале и в самом конце
String1 db "Введите массив $" String2 db "Введите диапазон [минимум и максимум] $" String3 db "Внутри диапазона лежит $" String4 db "чисел$"
sub ax,ax push ax
Что делают эти три строчки??? Для чего они
push ds
Почему push использутся БЕЗ pop ???!!! Есть такое правило сколько push стока pop! [если дело не касается вызова функций в форме C]
mov ah, 0
Лучше использовать xor ax,ax - быстрее и изящнее
mov di, offset nmass
Это нам уже не надо...
mov si, offset a Это нам уже не надо...
cmp al, [si] Здесь мы заменяем на конкретные переменные т.е. cmp al, [A]
cxz: cmp al, [si+1]
Здесь тоже
cxz: cmp al, [B]
mov [di],ah
- Заменю на вывод на экран.
ret
- ЧТО ТЫ ЭТИМ ДЕЛАЕШЬ? ЭТО ДЛЯ ЭТОГО У ТЕБЯ БЫЛИ СТРОКИ push ds sub ax,ax push ax ?
Объясни логику и где ты это взял =)
brut_
21.12.2004 15:38
Вообщем такое дело, я привел решение только второй задачи, возможно там есть что то лишнее . По поводу вопроса: такое дело: лекции нам по ассемблеру не читали, дали только методички и поставили лабы, типа на практике все и поймете... Отвечаю на вопрос (я буду цитировать из методы):
push ds - При запуске exe-программы регистр DS указывает на ее заголовок, считанной в память. Поэтому если тело программы описывается как процедура, то первой командой программы должна быть PUSH DS, которая сохраняет в стеке начальное значение DS.
ret - Выход из программы, описанной как дальняя процедура, осуществляется с помощью команды RETN или RET (типа конец процедуры).
push ax - поместить в стек нулевое смещение адреса возврата.
sub ax,ax - возможно - это то же лишнее.
Dark
22.12.2004 11:51
Имхо поизучай асм понастоящему =) по книгам
Это нестандартный способ,
программа завершается так
mov ah, 4Ch int 21h
Dark
22.12.2004 11:55
При этом в начале ничего не пушиться [я про push ;) ]
Dark
22.12.2004 20:51
Итак, решенная [без наворотов типа рамки] задача
Код
Мне пришлось сделать кое какое преобразование, для вводимых строк =) так как нам нужны числа [байт!], то
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 segment stack '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 segment assume cs: 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 byte ptr [si],30h; ASCII Не меньше 0? jl @break ; меньше cmp byte ptr [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;из строки в число