Ввод и сортировка строки - Assembler
Формулировка задачи:
Добрый день, необходимо обработать строку таким образом: первую треть строки по алфавитному порядку, вторую - по обратному алфавитному и последнюю - каждый символ предыдущим. Как реализовать перевод в ASCII и как можно сравнить два символа?
StrWork proc
mov dx, offset text2
call WrStr
lea dx, string
mov ah, 0ah
int 21h
xor bx, bx
xor dx, dx
lea si, string
strloop:lodsb
cmp al, 0dh
je strend
inc cl
jmp strloop
strend: mov ax, cl
mov bl, 3
div bl
xor bl, bl
str1:
inc bl
cmp bl, al
jl str1
push cl
sub cl, al
mov al, cl
pop cl
str2:
inc bl
cmp bl, al
jl str2
str3:
inc bl
cmp bl, cl
jl str3
StrWork endp StrWork proc
mov dx, offset text2
call WrStr
lea dx, string
mov ah, 0ah
int 21h
xor cl, cl
xor bx, bx
xor dx, dx
lea si, string
strloop:lodsb
cmp al, 0dh
je strend
inc cl
jmp strloop
strend: mov al, cl
cbw
mov bl, 3
div bl
xor bl, bl
str1: push al
lodsb
sub al, '0'
cmp al,
inc bl
pop al
cmp bl, al
jl str1
push cl
sub cl, al
mov al, cl
pop cl
str2: push al
lodsb
sub al, '0'
inc bl
pop al
cmp bl, ax
jl str2
str3: lodsb
sub al, '0'
sub al, 1
add al, '0'
inc bl
cmp bl, cl
jl str3
StrWork endp StrWork proc
mov dx, offset text2
call WrStr
lea dx, string
mov ah, 0ah
int 21h
xor cx, cx
xor bx, bx
xor dx, dx
lea si, string
strloop:lodsb
cmp al, 0dh
je strend
inc dl
jmp strloop
strend: mov al, dl
cbw
mov cx, ax
mov bl, 3
div bl
xor bh, bh
xor bl, bl
mnloop:
str1: push al
lodsb
sub al, '0'
mov bl, al
lodsb
cmp al, bl
jl
pop al
inc bh
cmp bh, al
jl str1
push cl
sub cl, al
mov al, dl
pop cl
str2: push al
lodsb
sub al, '0'
inc bh
pop al
cmp bl, ax
jl str2
str3: lodsb
sub al, '0'
sub al, 1
add al, '0'
inc bh
cmp bh, cx
jl str3
loop mnloop
StrWork endp StrWork proc
mov dx, offset text2
call WrStr
push cx dx
call Read_Keys
pop dx cx
strloop:lodsb
cmp al, 0dh
je strend
inc dl
jmp strloop
strend: mov al, dl
cbw
mov cx, ax
mov bx, 3
div bx
mnloop: xor bx, bx
str1: push ax
lodsw
sub ax, '0'
mov bx, ax
lodsb
cmp ax, bx
jl strel1
push cx
mov cx, ax
mov ax, bx
stosb
mov ax, cx
stosb
pop cx
strel1: pop ax
inc bx
cmp bx, ax
jl str1
push cx
sub cx, ax
mov ax, dx
pop cx
str2: push ax
lodsb
sub ax, '0'
mov bx, ax
lodsb
cmp ax, bx
jg strel2
push cx
mov cx, ax
mov ax, bx
stosb
mov ax, cx
stosb
pop cx
strel2: inc bx
pop ax
cmp bx, ax
jl str2
str3: lodsb
sub ax, '0'
sub ax, 1
add ax, '0'
stosb
inc bx
cmp bx, dx
jl str3
loop mnloop
mov dx, offset string
call WrStr
ret
StrWork endp StrWork proc
mov dx, offset text2
call WrStr
call Read_Keys
strend: mov al, cl
cbw
mov cx, ax
mov bx, 3
div bx
mnloop: xor bx, bx
str1: push ax
lodsw
sub ax, '0'
mov bx, ax
lodsw
cmp ax, bx
jl strel1
push cx
mov cx, ax
mov ax, bx
stosw
mov ax, cx
stosw
pop cx
strel1: pop ax
inc bx
cmp bx, ax
jl str1
push cx
sub cx, ax
mov ax, dx
pop cx
str2: push ax
lodsw
sub ax, '0'
mov bx, ax
lodsw
cmp ax, bx
jg strel2
push cx
mov cx, ax
mov ax, bx
stosw
mov ax, cx
stosw
pop cx
strel2: inc bx
pop ax
cmp bx, ax
jl str2
str3: lodsw
sub ax, '0'
sub ax, 1
add ax, '0'
stosw
inc bx
cmp bx, dx
jl str3
loop mnloop
mov dx, offset string
call WrStr
ret
StrWork endpStrWork proc
push ax bx cx dx si
mov dx, offset text2
call WrStr
call Read_Keys
lea dx, string+2
xor cx, cx
mov cl, string+1
mov al, cl
cbw
mov cx, ax
mov bl, 3
div bl
mov dl, al
xor bl, bl
mov dh, cl
mov ah, dl
strlp: push cx
stlp: lodsb
mov bh, al
lodsb
sub al, '0'
sub bh, '0'
cmp al, bh
jg strels1
mov ch, al
mov al, bh
add al, '0'
stosb
mov al, ch
add al, '0'
stosb
strels1:inc bl
cmp bl, dl
jl stlp
mov dl, dh
sub dl, ah
stlp1: lodsb
mov bh, al
lodsb
sub al, '0'
sub bh, '0'
cmp al, bh
jg strels2
mov ch, al
mov al, bh
add al, '0'
stosb
mov al, ch
add al, '0'
stosb
strels2:inc bl
cmp bl, dl
jl stlp1
stlp2: lodsb
sub al, '0'
sub al, 1
add al, '0'
stosb
inc bl
cmp bl, dl
jl stlp2
inc bl
cmp bl, cl
pop cx
loop strlp
mov ah, 40h
mov dx, 2
int 21h
call Read_Key
pop si dx cx bx ax
ret
StrWork endpРешение задачи: «Ввод и сортировка строки»
textual
Листинг программы
LOCALS @@ sseg segment stack 'stack' db 512 dup(?) sseg ends ;--------- Поля даних ----- dseg segment 'data' CRLF db 13, 10, '$' string db 0, 100 dup (?) keybuf db 102, ?, 100 dup (?) arr dw 20 dup(1) n=$-arr textmenu db 13, 10, 10 db ' ------------------------------------------------------------¬',13,10 db ' ¦ M E N U ¦',13,10 db ' +-----------------------------------------------------------+',13,10 db ' ¦ 1 - Put the sentence to work over it. ¦',13,10 db ' ¦ 2 - Fullfil an array (Between 0 and 20) ¦',13,10 db ' ¦ 0 - Exit. ¦',13,10 db ' L------------------------------------------------------------',13,10,10 db ' Your choice ? =>','$' text0 db 'The amount of negative elements in array is $' text1 db 'Enter the values of the elements: $' text2 db 'Put the sentence: ','$' text3 db 'The new sentence is: ','$' text4 db 'Enter amount of elements: $' errstr db 'Wrong number. Please, enter right value: $' buffer db 7, 8 dup(0) dseg ends ;---- Текст програми --- cseg segment 'code' assume cs:cseg, ds:dseg, ss:sseg start proc far mov ax, dseg mov ds, ax mov dx, 0018h m: call ClrScr call SetCur call Menu cmp dl, '1' je m1 cmp dl, '2' je m2 cmp dl, '0' jne m jmp endprog m1: call StrWork jmp m m2: call FillArr jmp m endprog: call ClrScr call SetCur mov ax, 4C00h int 21h start endp ;------------------------- Menu proc mov dx, offset textmenu call WrStr mov ah, 7 sign0: int 21h cmp al, '0' JL sign1 cmp al, '2' JG sign0 sign1: mov dl, al mov ah, 2 int 21h call NewLine call NewLine ret Menu endp ;------------------------- StrWork proc push ax bx cx dx ds es si di call ReadString call NewLine mov ah, 9 lea dx, String+1 int 21h call NewLine ;сортируем первую треть строки по возрастанию mov al, String ;находим длину массива mov ah, 0 mov cl, 3 div cl mov cl, al lea si, String+1 ;берём адрес массива call SortIncrease ;сортируем ;сортируем вторую треть массива по убыванию add si, cx call SortDecrease ;заключительную треть - заменить предыдущим символом add si, cx mov ax, cx mov cl, String+0 mov ch, 0 sub cx, ax sub cx, ax call PrevChars ;вывод результата mov ah, 9 lea dx, String+1 int 21h call NewLine ;ожидание нажатия call Read_Key pop di si es ds dx cx bx ax ret StrWork endp ;------------------------- FillArr proc push ax bx cx dx si di mov dx, offset text4 call WrStr push bx cx dx di call ReadNum pop di dx cx bx cmp ax, 0 jl mend cmp ax, 20 jg mend lea bx, [arr] mov cx, ax xor si, si push ax elm: mov dx, offset text1 call WrStr push bx cx dx si call ReadNum pop si dx cx bx mov [bx+si], ax add si, 2 call NewLine loop elm pop ax mov cx, ax call ClrScr mov dx, offset text0 call WrStr xor si, si mov ax, 0 mloop: cmp word ptr [bx+si], 0 jnle melse inc ax melse: add si, 2 loop mloop call Outpt call Read_Key pop di si dx cx bx ax mend: ret FillArr endp ;------------------------- Outpt proc xor cx, cx mov bx, 10 ot2: xor dx, dx div bx push dx inc cx test ax, ax jnz ot2 mov ah, 02h ot3: pop dx add dl, '0' int 21h loop ot3 Outpt endp ;------------------------- ;Чтение строки из консоли (с клавиатуры) ;Результат сохраняется в переменной String ;в формате: ;String+0 - размер строки ;String+1 - первый символ строки ReadString proc ;сохранение регистров push ax push cx push dx push si push di push ds push es pushf ;чтение строки в буфер ввода KeyBuf mov ah, 0Ah lea dx, KeyBuf int 21h ;копирование строки из буфера ввода mov ax, dseg mov ds, ax mov es, ax cld lea si, KeyBuf+1 lea di, String+0 mov cl, KeyBuf+1 mov ch, 0 mov String, cl inc cx ;т.к. копируется не только строка, но и байт длины строки rep movsb ;добавление в конец строки символа "конец строки" для вывода на экран mov al, '$' stosb ;восстановление регистров popf pop es pop ds pop di pop si pop dx pop cx pop ax ret ReadString endp ;------------------------- ;Сортировка по возрастанию ;si - адрес 0-го байта ;cx - количество SortIncrease proc push ax push cx push di push si mov di, si mov bx, cx dec bx @@ForI: mov cx, bx mov si, di inc si @@ForJ: mov al, [si] cmp al, [si-1] ja @@SkipExchange xchg al, [si-1] xchg al, [si] @@SkipExchange: inc si loop @@ForJ dec bx mov cx, bx jnz @@ForI pop si pop di pop cx pop ax ret SortIncrease endp ;------------------------- ;Сортировка по убыванию ;si - адрес 0-го байта ;cx - количество SortDecrease proc push ax push cx push di push si mov di, si mov bx, cx dec bx @@ForI: mov cx, bx mov si, di inc si @@ForJ: mov al, [si] cmp al, [si-1] jb @@SkipExchange xchg al, [si-1] xchg al, [si] @@SkipExchange: inc si loop @@ForJ dec bx mov cx, bx jnz @@ForI pop si pop di pop cx pop ax ret SortDecrease endp ;------------------------- PrevChars proc @@ForI: dec byte ptr [si] inc si loop @@ForI ret PrevChars endp ;------------------------- Read_Key proc push ax mov ah, 7 int 21h pop ax ret Read_Key endp ;------------------------- ClrScr proc push ax bx cx dx mov ax, 0600h mov bh, 07h mov cx, 0000h mov dx, 184fh int 10h pop dx cx bx ax ret ClrScr endp ;------------------------- ReadNum proc mov ah, 0ah xor di, di mov dx, offset buffer int 21h mov dl, 0ah mov ah, 02 int 21h mov si, offset buffer+2 cmp byte ptr [si], "-" jnz ii1 mov di, 1 inc si ii1: xor ax, ax mov bx, 10 ii2: mov cl, [si] cmp cl, 0dh jz endin cmp cl, '0' jl error cmp cl, '9' ja error sub cl, '0' mul bx add ax, cx inc si jmp ii2 error: mov dx, offset errstr call WrStr int 20h endin: cmp di, 1 jnz ii3 neg ax ii3: ret ReadNum endp ;------------------------- SetCur proc push ax bx mov ah, 02h mov bh, 00h int 10h pop bx ax ret SetCur endp ;------------------------- NewLine proc push dx mov dx, offset CRLF call WrStr pop dx ret NewLine endp ;------------------------- WrStr proc near mov ah,09h int 21h ret WrStr endp ; *********************** cseg ends end start