Помощь - Поиск - Пользователи - Календарь
Полная версия: 2 не очень сложных задачи
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
brut_
Помогите пожалуйста с двумя задачками:

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
Извини, но начну я с комертария =)

Я разбил задачи на два модуля [похоже ты хотел все сделать в одном]
Код

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_
Вообщем такое дело, я привел решение только второй задачи, возможно там
есть что то лишнее smile.gif.
По поводу вопроса:
такое дело: лекции нам по ассемблеру не читали, дали только методички и
поставили лабы, типа на практике все и поймете...
Отвечаю на вопрос (я буду цитировать из методы):

push ds - При запуске exe-программы регистр DS указывает на ее
заголовок, считанной в память. Поэтому если тело программы описывается как
процедура, то первой командой программы должна быть PUSH DS, которая
сохраняет в стеке начальное значение DS.

ret - Выход из программы, описанной как дальняя процедура, осуществляется
с помощью команды RETN или RET (типа конец процедуры).

push ax - поместить в стек нулевое смещение адреса возврата.

sub ax,ax - возможно - это то же лишнее.
Dark
Имхо поизучай асм понастоящему =) по книгам

Это нестандартный способ,

программа завершается так

mov ah, 4Ch
int 21h
Dark
При этом в начале ничего не пушиться [я про push ;) ]
Dark
Итак, решенная [без наворотов типа рамки] задача
Код

Мне пришлось сделать кое какое преобразование, для вводимых строк =)
так как нам нужны числа [байт!], то

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 - неправильный ввод

lea si,simv+2
xor cx,cx
mov cl,[bx-1]
Check:
cmp byte ptr [si],30h
jl @break
cmp byte ptr [si],39h
jq @break
inc si
loop Check

4. Переводим в число, в байт.
lea si,simv+2
xor cx,cx
mov cl,[si-1]
mov ax,[si]

;домножаем на 100
shl ax,1   ;ax=ax*4
mov [bx],ax
shl ax,4   ;ax=ax*16
add [bx],ax
shl ax,1   ;ax=ax*2
add [bx],ax
inc si
mov ax,[si]
;домножаем на 10
shl ax,1   ;ax=ax*2
add [bx],ax
shl ax,2   ;ax=ax*8
add [bx],ax
mov ax,[si+1]
;прибавляем остаток
add [bx],ax
Dark
Сама программа №2,

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;из строки в число

;домножаем на 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




; ==========================Начало программы====================


 start proc far
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 bx
loop 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

start endp
cd ends
end start


Вопросы? задавай
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.