Witam
To mój pierwszy post tak więc z góry przepraszam jeśli nie dopełniłem jakiegoś obowiązku odnośnie formatu postu itp, itd
Jeśli chodzi o programowanie to jestem całkowitym amatorem, tak więc prośba o wyrozumiałość. :)
Od niedawna zacząłem zabawy z asemblerem i z pomocą książek stworzyłem coś takiego w WinAsm.
Program przetwarza bajt pobrany z klawiatury na ciąg znaków
.model tiny
.data
liczby db "0123456789ABCDEF"
znak db ?,'$'
napis1 db 'Podaj znak: $'
napis2 db 'Podany znak ma wartosc: $'
clr db 13,10,'$'
.code
.startup
mov dx,offset napis1 ;wyswietlenie napis1
mov ah,09
int 21h
mov ah,0 ;pobranie znaku
int 16h
mov znak,al
mov dx,offset znak ;wyswietlenie znaku
mov ah,09
int 21h
mov al,znak ;zaladowanie znaku do di
mov di,ax
and di,000fh ;zamaskowanie starszych 12 bitow
mov bx,offset liczby ;zaladowanie do bx poczatku tablicy przegladowej "liczby"
mov ah,[bx+di]
mov [si+1],ah ;przeslanie do pamieci mlodszego znaku (na pozycji 2)
mov ah,24h
mov [si+2],ah ;przeslanie $ na pozycje 3 dla przerwania wyswietlania dla int 21h
xor ah,ah
mov al,znak ;ponownie zaladowanie znaku
mov di,ax
shr di,1
shr di,1
shr di,1
shr di,1 ;przesuniecie o 4 bity w prawo
and di,000fh ;zamaskowanie starszych 12 bitow
mov bx,offset liczby ;zaladowanie do bx aresu tablicy przegladowej "liczby"
mov ah,[bx+di]
mov [si],ah ;zaladowanie do pamieci wartosci znaku (na pozycje 1)
mov dx,offset clr ;wyswietlenie odh i oah
mov ah,09
int 21h
mov dx,offset napis2 ;wyswietlenie napis2
mov ah,09
int 21h
mov dx,si ;wyswietlenie wartosci podanego wczesniej znaku
mov ah,09
int 21h
mov ah,4ch
int 21h
.exit
end
Wszystko działa tak jak powinno. Z ciekawości zrobiłem mała modyfikację tego programu, a mianowicie zamieniłem rejestry DI i SI
między soba. Po zmianie kod wygląda tak
.model tiny
.data
liczby db "0123456789ABCDEF"
znak db ?,'$'
napis1 db 'Podaj znak: $'
napis2 db 'Podany znak ma wartosc: $'
clr db 13,10,'$'
.code
.startup
mov dx,offset napis1 ;wyswietlenie napisu 'podaj znak'
mov ah,09
int 21h
mov ah,0 ;pobranie znaku
int 16h
mov znak,al
mov dx,offset znak ;wyswietlenie znaku
mov ah,09
int 21h
mov al,znak
mov si,ax
and si,000fh ;zamaskowanie starszych 12 bitow
mov bx,offset liczby ;zaladowanie poczatku tablicy "liczby"
mov ah,[bx+si]
mov [di+1],ah ;przeslanie do pamieci "mlodszej" cyfry (na pozycji nr 2)
mov ah,24h ;zaladowanie do pamieci $ na 3 pozycje dla przerwania wyswietlania dla int 21h
mov [di+2],ah
xor ah,ah
mov al,znak ;zaladowanie ponownie znaku
mov si,ax
shr si,1
shr si,1
shr si,1
shr si,1 ;przesuniecie aby uzyskac starsze 4 bity
and si,000fh ;zamaskowanie pozostalych starszych 12 bitow
mov bx,offset liczby
mov ah,[bx+si]
mov [di],ah
mov dx,offset clr ;wyswietlenie 0dh i 0ah
mov ah,09
int 21h
mov dx,offset napis2 ;wyswietlenie drugiego napisu
mov ah,09
int 21h
mov dx,di ;wyswietlenie wartosci podanego znaku
mov ah,09
int 21h
mov ah,4ch
int 21h
.exit
end
W tym momencie wyświetlenie wartości znaku (mimo podania na pozycji [si+2] znaku $) nie kończy się tylko na samej wartości
ale zbiera z pamięci następne bajty i wyświetla je.
Oba programy sprawdziłem debugerami i w obu działanie jest identyczne (tylko DI i SI są zamienione).
Wpisanie na początku MOV DI,SI rozwiązuje problem
Tylko dlaczego tak się dzieje.....
Pewnie czegoś nie wiem, nie doczytałem (wiem że rejestr SI troche się różni od rejestru DI ale chyba w tak prostym programie nie powinno to mieć znaczenia), ogólnie tkwie w jakimś błednym myśleniu i mam nadzieje że ktoś mnie z tego wyprowadzi. Proszę o jakąś podpowiedź...