Assembler otázky

Programovacie jazyky, rady, poradňa...
F1L1P
Expert
Expert
Príspevky: 174
Registrovaný: 15 máj 2009, 20:45

Assembler otázky

Príspevok od používateľa F1L1P »

Co robim pri tychto ulohach zle ze mi vychadzaju zle vysledky?
Vysledky su 1. c, 2. 2050, 3. 0, 4. 35h

1. Je deklarovaná premenná R DB ´abcd´. Čo vypíše nasledujúca postupnosť inštrukcií?
mov di, 1; ulozim do registra di 1
mov dl, [R+di]; ulozim do dl b
dec di; znizim di o 1 cize v nom bude 0
inc dl; zvysim dl o 1 potom tam bude c?
mov ah, 2; ulozim do ah 2 naco ho tam ukladam?
int 21h; tento prikaz spravi co? Meni vysledok?

2. Aké číslo (v desiatkovej sústave) bude v registri AX po vykonaní nasledujúcej postupnosti inštrukcií?
mov ah, 2; ulozim do ah 2
mov bh, 3; ulozim do bh 3
add ah, bh; pripocitam k 2 cislo 3 co je 5
add ah, bh; pripocitam k 5 cislo 3 co je 8
mov al, 2; ulozim do al cislo 2
Spocitam ah+al a vyjde 82 a nie 2050 preco?

3. Sú deklarované premenné:
DATA
Data1 DB 0
Data2 DB 2
Data3 DB 4
Čo bude v BX po vykonaní nasledujúcich inštrukcií?
mov al, 2; ulozim do al 2
mov bx, offset Data1; ulozim do bx 0
mov [bx], al; ulozim do adresy bx 2 a vyjde mi 2 no ma vyjst 0

4. Predpokladajte, že pamäťové miesta 200h a 201h obsahujú čísla 12h a 34h. (Uvedené adresy chápte ako offset v dátovom segmente.) Čo bude v registri AH po vykonaní nasledujúcich inštrukcií?
mov bx, 200h; ulozim do bx 200
mov di, 1; ulozim do di 1
mov ax, 10Ah; ulozim do ax 10A to rozdelim na ah=1 a al=0A
add ah, [bx+di]; pripocitam k 1 cislo 201 cize 202 co je zle a ma vyjst 35
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: Assembler otázky

Príspevok od používateľa pcsiete »

F1L1P napísal:Co robim pri tychto ulohach zle ze mi vychadzaju zle vysledky?
Vysledky su 1. c, 2. 2050, 3. 0, 4. 35h

1. Je deklarovaná premenná R DB ´abcd´. Čo vypíše nasledujúca postupnosť inštrukcií?
mov di, 1; ulozim do registra di 1
mov dl, [R+di]; ulozim do dl b
dec di; znizim di o 1 cize v nom bude 0
inc dl; zvysim dl o 1 potom tam bude c?
mov ah, 2; ulozim do ah 2 naco ho tam ukladam?
int 21h; tento prikaz spravi co? Meni vysledok?
dec di už v tomto prípade nemá na výsledok žiaden vplyv, len ti má zamotať hlavu. V skutočnosti inc dl zvýši hodnotu dl z 0x42 ('b') na 0x43 ('c'). int 0x21 je prerušenie na komunikáciu s DOS-om, v tomto prípade je to funkcia 0x02, čiže vypísanie jedného znaku uloženého v dl na výstup.
2. Aké číslo (v desiatkovej sústave) bude v registri AX po vykonaní nasledujúcej postupnosti inštrukcií?
mov ah, 2; ulozim do ah 2
mov bh, 3; ulozim do bh 3
add ah, bh; pripocitam k 2 cislo 3 co je 5
add ah, bh; pripocitam k 5 cislo 3 co je 8
mov al, 2; ulozim do al cislo 2
Spocitam ah+al a vyjde 82 a nie 2050 preco?
Ty nespočítavaš al a ah, pretože ax nie je register obsahujúci ich súčet, ale 16-bitovú hodnotu skombinovanú z týchto dvoch. Teda ozajstným vzorcom je ax = (ah*256)+al.
3. Sú deklarované premenné:
DATA
Data1 DB 0
Data2 DB 2
Data3 DB 4
Čo bude v BX po vykonaní nasledujúcich inštrukcií?
mov al, 2; ulozim do al 2
mov bx, offset Data1; ulozim do bx 0
mov [bx], al; ulozim do adresy bx 2 a vyjde mi 2 no ma vyjst 0
Do bx nevložíš nulu, ale odsadenie nulového bajtu Data1 od aktuálneho segmentu, čo vyzerá byť v tomto prípade 0. Tým že na adresu na ktorú ukazuje bx vložíš 2 zmeníš síce ten bajt, no samotné bx nie, preto 0.
4. Predpokladajte, že pamäťové miesta 200h a 201h obsahujú čísla 12h a 34h. (Uvedené adresy chápte ako offset v dátovom segmente.) Čo bude v registri AH po vykonaní nasledujúcich inštrukcií?
mov bx, 200h; ulozim do bx 200
mov di, 1; ulozim do di 1
mov ax, 10Ah; ulozim do ax 10A to rozdelim na ah=1 a al=0A
add ah, [bx+di]; pripocitam k 1 cislo 201 cize 202 co je zle a ma vyjst 35
V poslednom kroku pripočítaš k ah to, čo je na adrese 201, teda 0x34. A 0x34+1 = 0x35.
F1L1P
Expert
Expert
Príspevky: 174
Registrovaný: 15 máj 2009, 20:45

Re: Assembler otázky

Príspevok od používateľa F1L1P »

Dakujem a co s takymi prikladmi

Spravna odpoved je 1
Su deklarovane premenne
.DATA
Data1 DB 2
Data2 DB 4
Data3 DB 6
Co bude v BX po vykonani nasledujucich instrukcii?
mov bx,offset Data2; ulozim do bx 4. bajt
inc byte ptr [bx]; ptr meni typ premennej ale tu nema co zmenit cize zvysim len na 5. adresu a preco vyjde 1?

A pri tejto ulohe ma vyjst cd
Je deklarovana premenna
R DB "abcd$"; co znamena ten $?
Co vypise nasledujuca postupnost instrukcii?
mov dx, offset R+2; ulozim do dx c
mov ah,9; ulozim do ah 9
int 21h
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: Assembler otázky

Príspevok od používateľa pcsiete »

Kód: Vybrať všetko

.DATA
Data1 DB 2
Data2 DB 4
Data3 DB 6

; co bude v BX po vykonani nasledujucich instrukcii?
mov bx,offset Data2; ulozim do bx 4. bajt
inc byte ptr [bx]; ptr meni typ premennej ale tu nema co zmenit cize zvysim len na 5. adresu a preco vyjde 1?
Neviem ako vám vysvetľovali koncept hodnôt a adries, ale asi vám nepovedali, že adresa je hodnota. Neexistuje nič ako typ premennej v assembleri, podobne ako neexistuje nič ako pointer na nejakú adresu. V praxi to znamená dve veci:
  1. kedže neexistuje typ a všetko je hodnota, nezáleží na tom čo je "ako aký typ" uložené, ale ako sa s tým pracuje
  2. z [1.] vyplýva, že to čo sa urobí s akýmkoľvek hodnotou či už v registri alebo pamäti nezávisí od toho, čo o nej povieš pri deklarácii, ale od toho čo s ňou budeš robiť v inštrukcii.

Kód: Vybrať všetko

.DATA
Toto je súčasť syntaxe nejakého assembleru (a toto je aj jeden z dôvodov prečo je assembler ako pojem nekonečne nepresný). .DATA znamená, že začíname segment dát a k čomukoľvek, o čom sa povie že sa nachádza v tomto segmente, sa dá pristupovať pomocou adresy relatívnej k tomuto segmentu. Jednoduchšie povedané, adresy sa tu začínajú počítať od nuly.

Kód: Vybrať všetko

Data1 DB 2 ; (offset Data1) = 0x00
Data2 DB 4 ; (offset Data2) = 0x01
Data3 DB 6 ; (offset Data3) = 0x02
offset je odsadenie, a kedže každá z položiek ktorú sme deklarovali má veľkosť presne jeden bajt, odsadenie od začiatku segmentu stúpa po každom bajte o neuveriteľný jeden bajt.

Kód: Vybrať všetko

mov bx, offset Data2
Do bx neukladáš ani 4-tý bajt v poradí, ani hodnotu 0x04. Ak sa pozrieš vyššie, uvidíš, že odsadenie (offset) od začiatku segmentu stúpa od nuly vždy o jeden bajt, teda:
  • ak je Data1 prvý bajt v poradí, tak jeho odsadenie bude 0 (pretože od segmentu je vzdialený na 0 bajtov ďaleko)
  • ak je Data2 druhý bajt v poradí, tak jeho odsadenie bude 1 (pretože od segmentu je vzdialený na 1 bajt -> Data1)
  • ak je Data3 tretí bajt v poradí, tak jeho odsadenie bude 2 (pretože od segmentu je vzdialený na 2 bajt -> Data1 a Data2)
Hodnota bx sa teda stáva 1.

Kód: Vybrať všetko

inc byte ptr [bx]; ptr meni typ premennej ale tu nema co zmenit cize zvysim len na 5. adresu a preco vyjde 1?
Tu je tá vec o ptr ktorej v tvojom podaní vôbec nerozumiem. ptr je len súčasť zápisu velkost ptr, ktorý hovorí, s akým množstvom dát má inštrukcia pracovať, pričom tieto dáta sú na adrese v hranatých zátvorkách.
Nijakým zvláštnym spôsobom sa neviaž na ptr, pretože oveľa častejšie (teda... eh... všade okrem MS assemblerov a produktov) sa stretneš iba s informáciou o veľkosti bajtu a zátvorkami (hranatými, okrúhlymi).

//autoeditácia príspevku (24 Nov 2014, 20:14)

Kód: Vybrať všetko

R DB "abcd$"; co znamena ten $?
DOS funkcia 0x09 (teda áno, ah je register, ktorý pri zavolaní prerušenia hovorí, akú funkciu si žiadaš) prijíma ako parameter adresu reťazca v bx, pričom tento reťazec musí byť ukončený $. Tento znak sa nevypíše, len značí, kde sa má s vypisovaním prestať.

Kód: Vybrať všetko

mov dx, offset R+2
Ako som už napísal vyššie, offset hovorí o vzdialenosti od začiatku segmentu. Reťazec R je nejaká položka v segmente, a jeho jednotlivé znaky (bajty) zastávajú pozície v segmente rovnako, ako keby bol každý jeden z nich deklarovaný osobitne...

Kód: Vybrať všetko

R_1 db 'a' ; offset neznámy
R_2 db 'b' ; (offset R_1)+1
R_3 db 'c' ; (offset R_1)+2
R_4 db 'd' ; (offset R_1)+3
R_5 db '$' ; (offset R_1)+4
Jediný rozdiel medzi situáciou predtým a situáciou teraz je, že v tvojom prípade si nemal pred premennou .DATA, čiže nevieš kde sa R v segmente nachádza a rozhodne nemáš zaručené, že je to na 0.
Takže, do dx ide jednoducho adresa (offset R)+2, teda adresa céčka.

Kód: Vybrať všetko

mov ah,9
int 21h
Už spomínané volanie funkcie operačného systému. Vypíše všetky bajty medzi adresou v dx a bajtom, ktorý má hodnotu $.
F1L1P
Expert
Expert
Príspevky: 174
Registrovaný: 15 máj 2009, 20:45

Re: Assembler otázky

Príspevok od používateľa F1L1P »

pcsiete napísal: offset je odsadenie, a kedže každá z položiek ktorú sme deklarovali má veľkosť presne jeden bajt, odsadenie od začiatku segmentu stúpa po každom bajte o neuveriteľný jeden bajt.
Kebyze zmenim DB za DW tak to bude stupat o 2 bajty a bude to vyzerat takto?
Data1 DW 2 ; (offset Data1) = 0x00
Data2 DW 4 ; (offset Data2) = 0x02
Data3 DW 6 ; (offset Data3) = 0x04
pcsiete
Medium Star
Medium Star
Príspevky: 413
Registrovaný: 07 dec 2012, 18:47

Re: Assembler otázky

Príspevok od používateľa pcsiete »

Áno.
... tak to bude stupat o 2 bajty ...
Presnejšie povedané, odsadenie bude stúpať o 2, kým segment sa bude zväčšovať o 2 bajty.
Napísať odpoveď