 |
Ассемблер в примерах - Удаление максимума и минимума массива
- Вопрос:
- нужно удалить максимум и минимум массива.
особенности реализации:
использовать процедуру вывода на экран.
разбить код программы на процедуры для лучшей читабельности.
применить передачу параметра через стек!!!
- Ответ:
-
.model tiny, C ; Делаем COM-файл и передаем параметр, как в С
.186
.code
org 100h
start:
mov ax, 3
int 10h ; устанавливаем текстовый режим
cld ; буду использовать строковые инструкции
; установим флаг направления
;выводим массив
call output, offset ar, arsize, offset srcArray
; определение минимального и максимального
call minmax, offset ar, arsize, offset min_el, offset max_el
; вывод минимального и максимального
call PrintNum, offset minElem, min_el
call PrintNum, offset maxElem, max_el
; удаляем минимальный и максимальные элементы
call DelMinMax, offset ar, arsize, min_el, max_el
; выведем результат
call output, offset ar, ax, offset dstArray
lea dx, PressKey
mov ah,9
int 21h
xor ax, ax
int 16h
int 20h
; две подпрограммы для вывода чисел на экран
writeWordDEC proc near
; вывод на экран слова в AX, воспринимается как беззнаковое
uses cx, dx, bx, ax
mov bx, 10
xor cx, cx
@@1:
xor dx, dx
div bx
push dx
inc cx
or ax, ax
jnz @@1
@@2:
pop ax
add al, '0'
int 29h ; это прерывание умеет делать только одно -
; выводить символ в AL на экран
LOOP @@2
ret
writeWordDEC endp
WriteWordDEC_signed proc
; вывод на экран слова в AX как знакового
; просто, если отрицательное, выводит минус, превращает в
; положительное и вызывает подпрограмму writeWordDEC
uses ax
or ax, ax
jns @@_no_sign
push ax
mov al, '-'
int 29h
pop ax
neg ax ; изменение знака на +
@@_no_sign:
CALL writeWordDEC
ret
WriteWordDEC_signed endp
;вывод на экран массива с заголовком
output proc addrarray:word, arraysize:word, prstring:word
uses cx, si, ax, dx
mov dx, prstring
mov ah, 9
int 21h
mov cx, arraysize
mov si, addrarray
jcxz @@output_ret ;вдруг пусто (например, все потерли) :)
@@_next:
lodsw
CALL writeWordDEC_signed
mov al, ' '
int 29h
int 29h
LOOP @@_next
@@output_ret:
ret
output endp
;определение мин и макс элементов
minmax proc array:word, count:word, addrmin:word, addrmax:word
uses si, dx, bx, cx, ax
mov si, array
lodsw
mov dx, ax ;мин
mov bx, ax ;макс
mov cx, count
@@_analize_next:
lodsw
cmp ax, dx
jge @@10
mov dx, ax
@@10:
cmp ax, bx
jle @@20
mov bx, ax
@@20:
LOOP @@_analize_next
mov si, addrmin ;сохраним по адресу мин
mov [si], dx
mov si, addrmax ;сохраним по адресу макс
mov [si], bx
ret
minmax endp
;вывод числа с заголовком
PrintNum proc string:word, num:word
uses dx, ax
mov dx, string
mov ah, 9
int 21h
mov ax, num
CALL writeWordDEC_signed
ret
PrintNum endp
DelMinMax proc, arr:word, arrsize:word, delmin:word, delmax:word
uses si, di, cx
mov si, arr ; адрес исходного массива
mov di, si ; сюда же будем писать и результат
mov cx, arrsize ;длина исходного массива
@@_delete_min_max_next:
lodsw
cmp ax, delmin ;если равен минимальному
je @@30
cmp ax, delmax ; или максимальному
je @@30 ; то проигнорируем
stosw ;иначе сохраним
@@30:
LOOP @@_delete_min_max_next
mov ax, di ;di - адрес за результатом
sub ax, arr ;ax - длина результата в байтах
shr ax, 1 ;ax - длина результата в словах
ret
DelMinMax endp
PressKey db 13,10,10,'Press any key ...$'
srcArray db 'Исходный массив:',13,10,'$'
maxElem db 13,10,'Максимальный элемент массива: $'
minElem db 13,10,'Минимальный элемент массива: $'
dstArray db 13,10,'Результирующий массив:',13,10,'$'
align 2
ar dw 1, 12, 23, -3, -4, 0, 7 ; сюда просто добавляйте числа, если хотите
arsize equ ($ - ar)/2 ; так определяется констата = размер массива в словах (число элементов)
; $ - операция вычисления текущего адреса
min_el dw 0
max_el dw 0
end start
|  |