03.12.2011, 23:27
общий
это ответ
Здравствуйте, Sanek!
Вот Вам полностью функциональная 16-битная программа со вводом и выводом.
[code h=207];В каждой пятерке массива а(15) найти второй по величине элемент,
;умножьте его на 2. Организовать массив b(3) из этих элементов
code segment 'code' ;начало сегмента кода
assume cs:code,ds:data,ss:stk
main proc
mov ax, data
mov ds, ax
mov es, ax
Input:
call InputA ;вводим массив А
jz ToFormB ;проверим размер числа
lea dx, sNumError ;число превысило 32767
mov ah, 9
int 21h
jmp Input ;на повтор ввода
ToFormB:
call FormB ;формируем В
call OutputB ;выводим В
PrintAny:
lea dx, sAny ;press any key
mov ah, 9
int 21h
mov ah, 0
int 16h ;ждем any key
mov ax, 4c00h
int 21h ;выход в ДОС
main endp
InputA proc ;вводим А
lea dx, sEnterA
mov ah, 9
int 21h ;приглашение на ввод элементов массива A
lea di, A ;адрес А
lea bp, [di+15*2] ;адрес за массивом (для контроля конца)
IA_ask:
lea dx, sNum ;приглашаем ко вводу
mov ah, 0ah
int 21h
lea si, sBuf ;строка с числами, разделенная разделителями
cld
IA_next:
cmp di, bp ;массив заполнен?
je IA_ok
call stoi ;[si] в число
jc IA_err ;ошибка разрядности?
jcxz IA_newrow ;дошли до конца строки?
stosw ;сохраняем
jmp IA_next ;на следующее число в строке
IA_newrow:
mov ah, 2
mov dl, 0ah
int 21h ;переход на новую строку
jmp IA_ask ;на запрос новой строки
IA_err:
or ax, 1 ;FZ == 0 -> ошибка размерности
IA_ok:
ret ;FZ == 1 -> все ок
InputA endp
FormB proc ;формируем массив В
lea si, A
lea di, B
mov cx, 3 ;3 пятерки
GroupsLoop:
push cx
mov cx, 5 ;число элементов в группе
xor dx, dx ;максимальное
xor bx, bx ;"предмаксимальное"
OneGroupLoop:
lodsw
cmp ax, bx ;сравним с предмаксимальным
jbe OneGroupNext ;<= - идем дальше
cmp ax, dx ;сравним с максимальным
je OneGroupNext ;одинаковые пропускаем
jb SetPrev ;меньше - сохраняем, как новый предмаксимальный
mov bx, dx ;больше - старый максимальный, как предмаксимальный
mov dx, ax ;новый, как новый максимальный
jmp OneGroupNext
SetPrev:
mov bx, ax ;новый предмаксимальный
OneGroupNext:
loop OneGroupLoop
mov ax,bx ;предмаксимальный
shl ax, 1 ;умножаем на 2
stosw ;сохраняем
pop cx
loop GroupsLoop
ret
FormB endp
OutputB proc ;выводим В
lea dx, sResult
mov ah, 9
int 21h ;вывод заголовока из dx
xor cx, cx ;счетчик элементов
OB_loop:
lodsw ;очередное значение
call itoa ;вывод числовой строки
inc cx ;считаем
cmp cx, 3 ;вывели 3?
je OB_ret
mov dl, ',' ;разделим запятой
int 21h ;ah = 2
jmp OB_loop
OB_ret:
ret
OutputB endp
itoa proc ;вывод беззнакового числа из ax
push cx ;сохраним счетчик колонок
mov bx, 10 ;будем делить на 10
xor cx, cx ;счетчик цифр
DivLoop:
xor dx, dx ;готовимся к делению dx:ax / bx
div bx ;ax - частное, dx - остаток=очередной младшей цифре
push dx ;сохраним цифру в стеке
inc cx ;посчитаем
test ax, ax ;продолжим, пока не 0
jnz DivLoop
mov ah, 2 ;функция вывода
PrintLoop: ;будем выводить в обратном порядке, начиная со старшей шифры
pop dx ;восстановим очередной разряд
or dl, '0' ;превратим в символ
int 21h ;выведем
loop PrintLoop
pop cx ;восстановим счетчик элементов
ret
itoa endp
stoi proc ;преобразование строки [si] в число AX
xor bx, bx ;здесь будем стоить число
xor cx, cx ;счетчик разрядов
stoi_next:
lodsb ;очередной символ
cmp al, 0dh ;конец стоки?
je stoi_eol
cmp al, '0'
jb stoi_sep ;любая нецифра - разделитель
cmp al, '9'
ja stoi_sep
push ax ;сохраним новый разряд
mov ax, 10
mul bx ;умножим старшие на 10
test dx, dx
pop dx ;новый
jnz stoi_err
test ax, ax
js stoi_err
and dx, 0fh ;'0'-'9' -> 0-9
add ax, dx ;добавляем новый разряд
js stoi_err
mov bx, ax ;сохраняем
inc cx ;считаем
jmp stoi_next ;продолжаем
stoi_sep: ;встретили разделитель
jcxz stoi_next ;были только разделители - на продолжение
; иначе - конец числа и выходим
stoi_eol: ; если числа нет и встретили 0dh - конец строки
mov ax, bx ;число возвращаем в ax
dec si ;шаг назад, чтобы легче было проанализировать 0dh
clc
ret
stoi_err:
stc
ret
stoi endp
code ends
data segment
sEnterA db 'Enter A (15 numbers): $'
sResult db 0dh,0ah,'B = $'
sNumError db 0dh,0ah,'Numbers must be < 32768',0dh,0ah,'$'
sAny db 0dh,0ah,'Press any key$',0
sNum db 80
len db ?
sBuf db 80 dup (?)
A dw 15 dup (?)
B dw 3 dup (?)
data ends
stk segment stack
dw 100h dup (?)
stk ends
end main
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен