Asembler
Asembler
Mam zadanie w którym muszę zmienić liczbę (dec) co ma jeden bajt na liczbę w systemie bin, hex i oct. Nie mogę wykorzystywać operacji dzielenia, tylko przesunięcia. Czy mógłby prosić by mi ktoś w bardzo prosty sposób wytłumaczyć jak ja mam to zrobić? Dzięki z góry.
Może taka mała podpowiedź: dzielenie przez 2 w systemie dziesiętnym (dec) to to samo, co przesunięcie o 1 pozycję w prawo w systemie binarnym (bin). Najstarszy bit uzupełniasz zerem, najmłodszy ginie, resztę przesuwasz.
hex to bin pogrupowany w czwórki i te czwórki zastępujemy symbolami hexa, przykład:
37dec = 100101bin = 0010 0101bin (grupujemy w czwórki i uzupełniamy zerami do pełnej czwórki z lewej) = 25hex
cyfry 10, 11, 12, 13, 14, 15 to odpowiednio A,B,C,D,E,F
Oct to samo, co wyżej, tyle że grupujesz w trójki.
A jeżeli chcesz to zrobić w asemblerze (jak sugeruje temat) to najlepiej przesuwać w prawo ciągle i spisywać resztę na bieżąco, potem odczytujesz te reszty od końca i już masz bin. Grupujesz w czwórki/trójki i masz hex/oct.
Czyli przykład:
25dec
>> - przesunięcie o 1 pozycję w prawo
25 >> 1 = 12 r. 1
12 >> 1 = 6 r. 0
6 >> 1 = 3 r. 0
3 >> 1 = 1 r. 1
1 >> 1 = 0 r. 1
I od końca jedziemy:
25dec = 11001bin
I masz bin.
Hex/oct wystarczy pogrupować teraz i zastąpić czwórki/trójki bitów odpowiednimi cyframi.
Co do kodu w asm, na jaki procesor to ma być? Jeżeli 8051 to może pomogę i z kodem
Ale gotowca nie dostaniesz.
hex to bin pogrupowany w czwórki i te czwórki zastępujemy symbolami hexa, przykład:
37dec = 100101bin = 0010 0101bin (grupujemy w czwórki i uzupełniamy zerami do pełnej czwórki z lewej) = 25hex
cyfry 10, 11, 12, 13, 14, 15 to odpowiednio A,B,C,D,E,F
Oct to samo, co wyżej, tyle że grupujesz w trójki.
A jeżeli chcesz to zrobić w asemblerze (jak sugeruje temat) to najlepiej przesuwać w prawo ciągle i spisywać resztę na bieżąco, potem odczytujesz te reszty od końca i już masz bin. Grupujesz w czwórki/trójki i masz hex/oct.
Czyli przykład:
25dec
>> - przesunięcie o 1 pozycję w prawo
25 >> 1 = 12 r. 1
12 >> 1 = 6 r. 0
6 >> 1 = 3 r. 0
3 >> 1 = 1 r. 1
1 >> 1 = 0 r. 1
I od końca jedziemy:
25dec = 11001bin
I masz bin.
Hex/oct wystarczy pogrupować teraz i zastąpić czwórki/trójki bitów odpowiednimi cyframi.
Co do kodu w asm, na jaki procesor to ma być? Jeżeli 8051 to może pomogę i z kodem
Składnia Intela (kompilator tasm).Luminofor pisze: Co do kodu w asm, na jaki procesor to ma być?
Za dobrze by mi byłoLuminofor pisze: Ale gotowca nie dostaniesz.
Czyli to będzie coś takiego:Luminofor pisze: Czyli przykład:
25dec
>> - przesunięcie o 1 pozycję w prawo
25 >> 1 = 12 r. 1
12 >> 1 = 6 r. 0
6 >> 1 = 3 r. 0
3 >> 1 = 1 r. 1
1 >> 1 = 0 r. 1
I od końca jedziemy:
25dec = 11001bin
mov al, 25 ; a tu trzeba wartość podawać binarnie (w tym wypadku 11001) czy tak normalnie pisać 25?
shr al, 1
shr al, 1
shr al, 1
shr al, 1
shr al, 1
W takim wypadku gdzie pojawia się ta reszta z tego przesunięcia o której mówisz i jak ją można wziąć od końca i wypisać na ekran?
Za pomocą pętli i przerwania int 21h bit po bicie? np.
mov dl, reszta
mov ah, 02h
int 21h
Jeden obrót pętli i wypisuje 1. Drugi obrót i znowu 1. Trzeci i 0 i tak długo aż powstaje liczba 11001 z tych 25 dec?
A jaką opcją się to grupuje w trójki, czwórki i dopisuje zera?Luminofor pisze:hex to bin pogrupowany w czwórki i te czwórki zastępujemy symbolami hexa, przykład:
37dec = 100101bin = 0010 0101bin (grupujemy w czwórki i uzupełniamy zerami do pełnej czwórki z lewej) = 25hex
cyfry 10, 11, 12, 13, 14, 15 to odpowiednio A,B,C,D,E,F
Oct to samo, co wyżej, tyle że grupujesz w trójki.
Powiedz mi proszę jeszcze jak stworzyć bufor na tą 8-bitową liczbę tak by nie można było podać liczby większej czy wpisać jakiegoś znaku.
Czyli asembler 8086... Niestety tego asm znam w stopniu mizernym, 8051 juz całkiem całkiem.Goenitz pisze:Składnia Intela (kompilator tasm).
No właśnie.Goenitz pisze:Za dobrze by mi było. I wtedy nic się nie nauczę
.
Niestety nie znam zbytnio tego asemblera x86Goenitz pisze:Czyli to będzie coś takiego:
mov al, 25 ; a tu trzeba wartość podawać binarnie (w tym wypadku 11001) czy tak normalnie pisać 25?
shr al, 1
shr al, 1
shr al, 1
shr al, 1
shr al, 1
W takim wypadku gdzie pojawia się ta reszta z tego przesunięcia o której mówisz i jak ją można wziąć od końca i wypisać na ekran?
Ale pierwszy link w google:
http://rudy.mif.pg.gda.pl/~bogdro/dos/a_kurs13.htm
Podawać binarnie raczej nie trzeba, a z cytatu wynika, że resztę masz we fladze CF - musisz ją sobie po każdym przesunięciu gdzieś przepisać np. do jakiegoś rejestru bo przy następnym przesunięciu ulegnie nadpisaniu. Przepisujesz i przesuwasz w lewo żeby zrobić miejsce dla następnej reszty, i dodajesz or'em żeby znowu nie nadpisać poprzednich reszt.Niech na początku AX = 1010 0101 1010 0101 (A5A5h).
...
Instrukcja SHR działa w drugą stronę niż SHL: bit zerowy jest umieszczany we fladze CF, każdy inny bit wchodzi na miejsce bitu młodszego o 1, a do najstarszego bitu wkładane jest zero.
Dlatego teraz po wykonaniu SHR AX,1 w rejestrze AX będzie 0001 0110 1001 0100 (1694h), bo poprzednie bity AX przesunęliśmy o 1 miejsce w prawo, oraz CF=0.
Tu niestety nie pomogę - assembler 8086 nie jest moją mocną stroną, preferuję asm 8051Goenitz pisze:Za pomocą pętli i przerwania int 21h bit po bicie? np.
mov dl, reszta
mov ah, 02h
int 21h
Jeden obrót pętli i wypisuje 1. Drugi obrót i znowu 1. Trzeci i 0 i tak długo aż powstaje liczba 11001 z tych 25 dec?
Musisz to sam wymyślić, gotowej funkcji w asemblerze na to nie maGoenitz pisze:A jaką opcją się to grupuje w trójki, czwórki i dopisuje zera?
W 8051 było coś takiego jak LOW/HIGH i tam to chodziło chyba o górny/dolne 4 bity z bajtu ale pewny nie jestem. Może w 8086 jest coś podobnego. Zawsze możesz zastosować "maskowanie" tzn. robisz maskę 1111 0000 i dajesz logicznego and'a i już masz 4 starsze bity.
Bufor możesz stworzyć w jakimś rejestrze pomocniczym. A i instrukcje skoków warunkowych też ktoś po coś wymyślił.Goenitz pisze:Powiedz mi proszę jeszcze jak stworzyć bufor na tą 8-bitową liczbę tak by nie można było podać liczby większej czy wpisać jakiegoś znaku.
P.S. z kodem pod 8086 Ci nie pomogę, ale przedstaw algorytm słowami to się wypowiem
W sumie każda książka o Z80 (poza instrukcjami rozszerzonymi) czy 8080/85 odpowie na twoje pytania, bo jak dobrze pamiętam procesory 8086/88 są wstecznie kompatybilne z 8080/85 czyli wykonają program dla niego napisany, przy czym trzeba pamiętać o specyficznym sposobie adresownia pamięci w x86.
Jeżeli nie możesz używać instrukcji mnożenia i dzielenia, to napisz sobie 2 procedury które będą to robiły instrukcjami przesunięć.
Ps. gdzieś mam wydruk gotowej biblioteki arytmetycznej dla 8080, muszę poszukać. SIN, cos, BCD<>BIN, mnożenie, dzielenie i coś tam jeszcze.
Pocedura konwersji 6 znaków ASCII reprezentujących liczbę ósemkową na 16-bitową wartość przekazywaną do pary HL.
UWAGA I:
Nie sprawdza się poprawności znaków i ewentualnego przekroczenia pojemności pary HL.
UWAGA II:
Przepisywałem ze starego Xero wiec mogłem się przypadkiem gdzieś pomylić. Procedura jest wycinkiem całej biblioteki dla I8080.
Jeżeli nie możesz używać instrukcji mnożenia i dzielenia, to napisz sobie 2 procedury które będą to robiły instrukcjami przesunięć.
Ps. gdzieś mam wydruk gotowej biblioteki arytmetycznej dla 8080, muszę poszukać. SIN, cos, BCD<>BIN, mnożenie, dzielenie i coś tam jeszcze.
Pocedura konwersji 6 znaków ASCII reprezentujących liczbę ósemkową na 16-bitową wartość przekazywaną do pary HL.
UWAGA I:
Nie sprawdza się poprawności znaków i ewentualnego przekroczenia pojemności pary HL.
UWAGA II:
Przepisywałem ze starego Xero wiec mogłem się przypadkiem gdzieś pomylić. Procedura jest wycinkiem całej biblioteki dla I8080.
Kod: Zaznacz cały
ASOCT: PUSH PSW ; PRZECHOWAJ REJESTRY
PUSH B
PUSH D
XCHG ; INDEKS DO DE
LXI H,0 ; W HL BEDZIE WYNIK
MVI B,6 ; LICZNIK PETLI NA 6 ZNAKOW
PETLA: LDAX D ; ZNAK W AKUMULATORZE
ANI 177Q ; ZERUJ BIT PARZYSTOSCI
SUI 60Q ; KONWERSJA ZNAK ASCII->CYFRA
ORA L ; SKLADANIE WYNIKU
MOV L,A
INX D ; NOWY INDEX
DCR B ; ZMNIEJSZ LICZNIK
JZ GOTOW
DAD H ; PRZESUWAMY NA POZYCJE NASTEPNEJ CYFRY
DAD H
DAD H
JMP PETLA
GOTOW:POP D
POP B
POP PSW
RET