Организация ввода пользователем заданного числа элементов массива - Assembler
Формулировка задачи:
Задача: перегруппировать элементы целочисленного массива: чтобы сначала шли отрицательные, потом нулевые, потом положительные элементы (порядок следования в каждой группе сохранить). Задачу реализовала, но у меня изначально вводилось 10 элементов, пытаюсь переделать , чтобы сначала вводили необходимое число элементов, а потом ввод и когда отображается строка "результат" появляются страшная музыка и крокозябры...уже не знаю что и делать
EXTRN Cursor:Far,Clear:Far,Write_Str:Far,Vvod:Far,Vyvod:Far
;------------------ Сегмент стека -------------------------
Stacksg SEGMENT PARA STACK
DW 128 DUP(?)
Stacksg ENDS
;--------------------- Сегмент данных---------------------
Datasg SEGMENT PARA
STR1 DB "количество: $"
STR2 DB "Последовательность: $"
STR3 DB "Результат: $"
count DW 0
X DW 0
MPOL DW 20 DUP(?)
MOTR DW 20 DUP(?)
MNUL DW 20 DUP(?)
KP DW 0
KO DW 0
KN DW 0
MAS DW 20 DUP(?)
Datasg ENDS
;---------------------Кодовый сегмент --------------------
Codesg SEGMENT PARA
begin PROC FAR
;Пролог EXE-программы.
;Выполнение первого требования.
ASSUME CS:Codesg, DS:Datasg, SS:Stacksg
;Выполнение второго требования.
PUSH DS ; Записать DS в стек.
;Выполнение третьего требования.
XOR AX,AX ; Установить в нуль AX.
PUSH AX ; Записать AX в стек.
;Выполнение четвертого требования.
MOV AX,Datasg ; Занести адрес
MOV DS,AX ; Datasg в DS.
;Завершение пролога EXE-программы.
CALL Clear
MOV DX,0000H
CALL Cursor
Lea dx,STR1 ; вводим количество
call Write_Str
mov dx, 0013H
call Cursor
call Vvod
mov count,bx
MOV DX,0200H
CALL Cursor
LEA DX,STR2 ;Загрузка адреса сообщения.
CALL Write_Str
MOV DX,0212H
LEA SI,MAS
MOV CX,count
BEG2:
ADD DX,3 ; ввод массива
CALL Cursor
CALL Vvod
MOV [SI],BX
ADD SI,2
LOOP BEG2
MOV DX,0300H
CALL Cursor
LEA DX,STR3 ;Загрузка адреса сообщения.
CALL Write_Str
LEA SI,MAS
MOV CX,count
BEG1:
MOV AX,[SI]
CMP AX,0
JL OTR ; если меньше 0
JE NU ; если равно
LEA BX,MPOL ; заполнение массива полож
mov ax,kp ; кол-во полож
MOV DX, 2
MUL DX
add bx,ax
MOV DX,[SI]
MOV [BX],DX
INC KP
JMP A2
OTR: ;заполнение массива отриц
LEA BX,MOTR
mov ax,ko
MOV DX, 2
MUL DX
add bx,ax
MOV DX,[SI]
MOV [BX],DX
INC KO
JMP A2
NU: ; заполнение массива нулей
LEA BX,MNUL
mov ax,kn
MOV DX, 2
MUL DX
add bx,ax
MOV DX,[SI]
MOV [BX],DX
INC KN
A2:
ADD SI,2 ; смещение на след эл-т
LOOP BEG1
;записываем обратно в массив
LEA SI,MAS
LEA BX,MOTR
MOV AX,KO
JE BEG22 ; если нет отриц то переходи к 0
MOV CX,KO
BEG21:
MOV AX,[BX]
MOV [SI],AX
ADD SI,2
ADD BX,2
LOOP BEG21
BEG22:
LEA BX,MNUL
MOV AX,KN
JE BEG33
MOV CX,KN
BEG3:
MOV AX,[BX]
MOV [SI],AX
ADD SI,2
ADD BX,2
LOOP BEG3
BEG33:
LEA BX,MPOL
MOV AX,KP
JE BEG44
MOV CX,KP
BEG4:
MOV AX,[BX]
MOV [SI],AX
ADD SI,2
ADD BX,2
LOOP BEG4
mov dx,0400H
call Cursor
LEA SI,MAS
MOV CX,count
BEG44: ; вывод массива
MOV BX,[SI]
ADD DX,3
CALL Cursor
CALL Vyvod
ADD SI,2
loop BEG44
begin ENDP
Codesg ENDS
END beginРешение задачи: «Организация ввода пользователем заданного числа элементов массива»
textual
Листинг программы
; Fasm code........
org 100h
jmp start
mes0 db 13,10,' Кол-во элементов: $'
mes1 db 13,10,' Введите массив..: $'
mes2 db 13,10,' Результат.......: $'
buff db 80 dup(0) ; буфера
mOtr db 32 dup('*') ;
mNul db 32 dup('*') ;
mPol db 32 dup('*') ;
count dw 0 ; длина массива
flag db 0 ; флаг отрицательных
start: mov dx,mes0 ;
call Message ;
call asc2hex ; принимаем кол-во с клавы
mov [count],di ; запомним..
;--- Заполняем массив указанным кол-вом элементов --------------------//
mov dx,mes1 ;
call Message ;
mov cx,di ; кол-во чисел для ввода
mov si,buff ; куда сохранять
createArray: ;
call asc2hex ; принимаем очередное число..
int 29h ; вставляем запятую/разделитель
xchg ax,di ;
mov byte[si],al ; сохраняем по-адресу SI
inc si ; шаг вперёд в буфере
loop createArray ; мотаем цикл СХ-раз..
;--- Сортируем данные по-буферам -------------------------------------//
mov cx,[count] ; длина массива
mov si,buff ; источник данных
mov di,mOtr ; адреса приёмников
mov bx,mNul ; ^
mov bp,mPol ; ^
cycle: lodsb ; берём байт из SI
or al,al ; взводим флаги!
jns null ; прыг, если SF=0 (число не отрицательное)
mov byte[di],al ; иначе: отправляем байт по-адресу(di)
inc di ; смещаемся в буфере
jmp sort ; продолжить цикл..
null: jnz nzero ; прыг, если ZF=0 (число не является нулём)
mov byte[bx],al ;
inc bx ;
jmp sort ;
nzero: mov byte[bp],al ; значит положительное!
inc bp ;
sort: loop cycle ; мотаем цикл СХ-раз..
;--- Выводим отсортированные данные на экран -------------------------//
mov dx,mes2 ;
call Message ;
xor ax,ax ;
mov si,mOtr ;<-------; сначала отрицательные!
prn1: lodsb ;
cmp al,'*' ; пока не встретится маркер конца
je prn2 ;
neg al ; инверсия отриц.числа для вывода
push ax ;
mov al,'-' ; вставляем знак
int 29h ;
pop ax ;
call hex2asc ; выводим очередное число на экран
mov al,',' ; вставляем разделитель чисел
int 29h ;
jmp prn1 ; на повтор..
prn2: xor ax,ax ;<------; теперь нули!
mov si,mNul ;
@mNul: lodsb ;
cmp al,'*' ;
je prn3 ;
call hex2asc ;
mov al,',' ;
int 29h ;
jmp @mNul ;
prn3: xor ax,ax ;<------; в конце положительные!
mov si,mPol ;
@mPol: lodsb ;
cmp al,'*' ;
je exit ;
call hex2asc ;
mov al,',' ;
int 29h ;
jmp @mPol ;
exit: xor ax,ax ; ждём клавишу..
int 16h ;
int 20h ; на выход!
;ннннннннннннн П Р О Ц Е Д У Р Ы нннннннннннннннннннннннннннннннннннннн
Message: ;
mov ah,9 ;
int 21h ;
ret ;
;----------------------------------------------------------------------
; Ввод чисел с клавиатуры.
; На выходе получаем 10-тичное число в DI. Есть проверка на знак.
; Заканчивает ввод по двум клавишам: 'Enter' и ',' (запятая).
; Enter заканчивает ввод длины массива, Запятая - ввод чисел в массив.
asc2hex: ;
push si ;
mov [flag],0 ; очищаем флаг отрицательных
xor di,di ;
mov si,10 ; множитель для системы счисления
@@1: xor ax,ax ; ждём клавишу..
int 16h ;
cmp al,'-' ; если минус,
jne @@2 ;
int 29h ; ..то выводим его,
inc [flag] ; ..устанавливаем флаг
jmp @@1 ; ..и читаем сл.клавишу
@@2: cmp al,13 ; Enter?
je stop ;
cmp al,',' ; разделитель?
je stop ;
cmp al,'0' ; игнорируем буквы
jb @@1 ;
cmp al,'9' ;
ja @@1 ;
int 29h ; покажем ввод
and ax,0fh ;
xchg di,ax ;
xor dx,dx ;
mul si ;
add di,ax ; и сохраняем число в DI
jmp @@1 ; сл.разряд числа..
; юзер прекратил ввод!
stop: cmp [flag],0 ; проверим на отрицательное
je okey ;
neg di ; инверсия (если нужно)
okey: pop si ;
ret ; выходим из процедуры ввода!
;---------------------------------------------------------------------------
hex2asc: ; Функция переводит числа в символы
pusha ; Вход: АХ = число, BX = система счисления
xor cx,cx ; Выход: на экране
mov bx,10 ;
isDiv: xor dx,dx ;
div bx ;
push dx ;
inc cx ;
or ax,ax ;
jnz isDiv ;
isOut: pop ax ;
add al,30h ;
int 29h ;
loop isOut ;
popa ;
ret ;