Подскажите как увеличить рабочие биты - Assembler
Формулировка задачи:
Доброго времени суток. у меня есть задание:
Матрица размером 6х8 состоит из целых чисел, каждое из которых принадлежит диапазону от -32768 до +32767. Требуется переставить столбцы матрицы в порядке убывания сумм их элементов. Если все числа в матрице равны, следует вывести на экран соответствующее сообщение.
Обмен информацией с пользователем организовать в виде специальных сообщений, каждое из которых следует размещать в отдельной строке экрана.
Прогу я написал(корявенько но все же), все работает, но только при определенных условиях. числа у меня записываются в 16-битные регистры (т.к. диапазон от -32768 до +32767). Если будет ситуация что промежуточная сумма чисел столбцов будет выходить из диапазона или конечная сумма, тогда данные будут не верные. К примеру столбец со значениями:32767,32767,32767,32767,327670,32767,32767,32767; сумма будет 262136. так же может быть -262136. то есть необходимо 19 бит, где их найти ума не приложу.
я подобрал числа чтобы промежуточная и конечная сумма была от -32768 до +32767, поэтому и работает)
но все же это надо будет сдавать, подскажите как это можно исправить. программа пишется в эмуляторе emu8086, 16 разрядные регистры(. буду очень благодарен за помощь. код ниже.
data segment
s1 db 'vse chisla ravni',0dh,0ah,'$'
s2 db 'ishodnii massiv:',0dh,0ah,'$'
s3 db ,0dh,0ah,'$'
s4 db 'sortirovanii massiv:',0dh,0ah,'$'
s5 db 'vivod summ stolbcov(ne sortir):',0dh,0ah,'$'
s6 db 'vivod summ stolbcov sortirov:',0dh,0ah,'$'
mas1 dw 17294,7222,311,-600,1,4829,4821,-564,-12,-7453,-6944,-11341,-23649,321,28749,281,11689,7893,781,17,-5490,-1342,3274,12,7654,-7893,2345,-7892,-564,14563,3210,30000,-12000,6780,-13248,-2340,-11698,-14280,11345,-2111,-2569,-12,23420,-27610,6782,3456,-22300,-2001
mas2 dw 6 dup(0)
buffer equ $
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
mov ax, data
mov ds, ax
mov es, ax
mov ah,09h ;vivod stroki s2
lea dx, s2
int 21h
call vivod ;vivod ishodnii mas1
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
xor di,di
mov cx,48 ;proverka, vse chisla ravni?
a0: mov ax,mas1[di]
mov bx,mas1[di+2]
cmp ax,mas1[di+2]
jne a1 ;perehod esli ne ravni
inc di
inc di
loop a0
mov ah,09h ;vivod stroki s1
lea dx, s1
int 21h
a1:
xor bx,bx
xor di,di
xor ax,ax
xor si,si
mov cx,6
a2:
push cx
push di
call summ ; procedura podscheta summu stolbcov, u zapis rezult v mas2
pop di
inc di
inc di
pop cx
loop a2
mov ah,09h ;vivod stroki s5
lea dx, s5
int 21h
call vivod_s
xor si,si
mov cx,6
push cx
a6: ;sortirovka puzerkom
dec cx
cmp cx,0
push cx
je z1
a3:
mov ax,mas2[si] ;sravnivaem summu stolbcov
mov bx,mas2[si+2]
cmp ax,mas2[si+2]
jl a4 ; esli menshe
inc si
inc si
loop a3
pop cx
xor si,si
jmp a6
a4:
push cx ; men9em mestami chisla v mas1
mov cx,8
mov di,si
a5:
mov ax,mas1[di]
mov bx, mas1[di+2]
mov mas1[di],bx
mov mas1[di+2],ax
add di,12
loop a5
mov ax,mas2[si] ; ; men9em mestami chisla v mas2
mov bx,mas2[si+2]
mov mas2[si],bx
mov mas2[si+2],ax
inc si
inc si
pop cx
dec cx
cmp cx,0
je a7
jmp a3
a7:
pop cx
xor si,si
jmp a6
z1:
mov ah,09h ;vivod stroki s6
lea dx, s6
int 21h
call vivod_s
mov ah,09h ;vivod stroki s4
lea dx, s4
int 21h
call vivod ;vivod sortirovonnogo mas1
int 20h
summ proc
mov cx,8
xor bx,bx
p1:
mov ax,mas1[di]
add bx,ax
add di,12
loop p1
mov mas2[si],bx
inc si
inc si
ret
summ endp
proc vivod
xor si,si
mov cx,8
vivod1:
push cx
mov cx,6
vivod2:
mov ax,mas1[si]
call print_word_sdec
mov dl,' '
mov ah,2h
int 21h
inc si
inc si
loop vivod2
mov ah,09h ;vivod stroki s3
lea dx, s3
int 21h
pop cx
loop vivod1
ret
vivod endp
proc vivod_s
xor si,si
mov cx,6
sum:
mov ax,mas2[si]
call print_word_sdec
mov dl,' '
mov ah,2h
int 21h
inc si
inc si
loop sum
mov ah,09h ;vivod stroki s3
lea dx, s3
int 21h
ret
vivod_s endp
print_word_sdec:
push di
mov di,buffer ;DI = ????? ??????
push di ;?????????? DI ? ?????
call word_to_sdec_str ;?????????????? ????? ? AX ? ??????
mov byte[di],'$' ;?????????? ??????? ????? ??????
pop di ;DI = ????? ?????? ??????
call print_str ;????? ?????? ?? ???????
pop di
ret
word_to_sdec_str:
push ax
test ax,ax ;???????? ????? AX
jns wtsds_no_sign ;???? >= 0, ??????????? ??? ???????????
mov byte[di],'-' ;?????????? ????? ? ?????? ??????
inc di ;????????? DI
neg ax ;????????? ????? ???????? AX
wtsds_no_sign:
call word_to_udec_str ;?????????????? ???????????? ????????
pop ax
ret
print_str:
push ax
mov ah,9 ;??????? DOS 09h - ????? ??????
xchg dx,di ;????? ?????????? DX ? DI
int 21h ;????????? ? ??????? DOS
xchg dx,di ;????? ?????????? DX ? DI
pop ax
ret
word_to_udec_str:
push ax
push cx
push dx
push bx
xor cx,cx ;????????? CX
mov bx,10 ;? BX ???????? (10 ??? ?????????? ???????)
wtuds_lp1: ;???? ????????? ???????? ?? ???????
xor dx,dx ;????????? ??????? ????? ???????? ?????
div bx ;??????? AX=(DX:AX)/BX, ??????? ? DX
add dl,'0' ;?????????????? ??????? ? ??? ???????
push dx ;?????????? ? ?????
inc cx ;?????????? ???????? ????????
test ax,ax ;???????? AX
jnz wtuds_lp1 ;??????? ? ?????? ?????, ???? ??????? ?? 0.
wtuds_lp2: ;???? ?????????? ???????? ?? ?????
pop dx ;?????????????? ??????? ?? ?????
mov [di],dl ;?????????? ??????? ? ??????
inc di ;????????? ?????? ??????
loop wtuds_lp2 ;??????? ?????
pop bx
pop dx
pop cx
pop ax
ret
ends
end startРешение задачи: «Подскажите как увеличить рабочие биты»
textual
Листинг программы
not ax inc ax
Объяснение кода листинга программы
not ax- здесь происходит инверсия (обращение) значения регистра AX.inc ax- увеличивается значение регистра AX на единицу. Этот код на языке Assembler выполняет две операции: сначала инвертирует значение регистра AX, а затем увеличивает его на единицу.