Организация ввода пользователем заданного числа элементов массива - 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 ;
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д