programowanie niskopoziomowe spr1


Jacek Pieprzak Rzeszów 31.10.2011r.

L04

Programowanie niskopoziomowe

Sprawozdanie z laboratorium

Temat: Zmienne, adresy, wskaźniki

Kod programu analizowanego na zajęciach:

char c,c1,c2;

int i;

char Tabl[10];

char Napis[] = "asembler";

char *ptr;

struct hilo {char l; char h;};

union u1 { int i;

struct hilo c;};

union u1 utab[4];

union u1 *uptr;

void main(void)

{

c=1;

i=-1;

ptr=Tabl;

*ptr++=1;

*ptr++=2;

c=*((ptr--)-1);

utab[0].i =0x2211;

utab[1].c.l=0x33;

utab[1].c.h=0x44;

utab[2].c.l=0x55;

utab[2].c.h=0x66;

ptr=(char *)&utab[0];

i=*(ptr+1);

ptr = (char *) ((union u1 *)ptr+1);

c1=*ptr++;

c2=*ptr++;

uptr = utab;

i=(uptr+1)->i;

uptr++;

i=(uptr+1)->i;

}

Kod dla modelu typu Small

//Pozwala na asemblowanie jeśli nazwa została zdefiniowana.

ifndef ??version

//Makroinstrukcja

?debug macro

endm

publicdll macro name

public name

endm

endif

?debug V 300h

?debug S "..\USER\MAIN.CPP"

?debug C E91253583B102E2E5C555345525C4D41494E2E435050

//deklaracja segmentu typu byte, o typie łączenia public i klasie `CODE', o nazwie _TEXT

_TEXT segment byte public 'CODE'

//koniec deklaracji segmentu

_TEXT ends

//wiązanie segmentu _DATA, _BSS w jedną grupe DGROUP

DGROUP group _DATA,_BSS

//przypisanie etykiet rejestrom cs i ds

assume cs:_TEXT,ds:DGROUP

//deklaracja segmentu typu byte

_DATA segment word public 'DATA'

//przypisanie etykiet danym typom

d@ label byte

d@w label word

_DATA ends

//deklarascja segmentu _BSS

_BSS segment word public 'BSS'

b@ label byte

b@w label word

//przypisanie etykiet zmiennym oraz deklaracja zmiennej o rozmiarze 1 bajta, wypełniona //nieokreślonymi wartościami

_c label byte

db 1 dup (?)

_c1 label byte

db 1 dup (?)

_c2 label byte

db 1 dup (?)

//przypisanie etykiety _i zmiennej typu word oraz deklaracja zmiennej o rozmiarze 2 bajtów, //wypełniona nieokreślonymi wartościami

_i label word

db 2 dup (?)

//przypisanie etykiety _Tabl oraz deklaracja tablicy o rozmiarze 10 bajtów, wypełniona //nieokreślonymi wartościami

_Tabl label byte

db 10 dup (?)

//koniec deklaracji segmentu _BSS

_BSS ends

//deklaracja segmentu danych

_DATA segment word public 'DATA'

//przypisanie etykiety _Napis do zmiennej typu byte, oraz wpisanie do niej wartości hex //odpowiadające napisowi zadeklarowanemu w programu w kodzie ASCII

_Napis label byte

db 97

db 115

db 101

db 109

db 98

db 108

db 101

db 114

db 0

_DATA ends

//deklaracja pozostałych elementów,

_BSS segment word public 'BSS'

_ptr label word

db 2 dup (?)

_utab label word

db 8 dup (?)

_uptr label word

db 2 dup (?)

_BSS ends

//deklaracja segmentu kodu

_TEXT segment byte public 'CODE'

;

; void main(void)

;

//przypisanie etykiety _TEXT rejestru cs

assume cs:_TEXT

//deklaracja procedury _main, wywoływanie bliskie (w tym samym segmencie kodu)

_main proc near

//położenie rejestru bp na stosie

push bp

//umieszczenie w rejestrze bp wartości wskaźnika stosu

mov bp,sp

//przypisanie do zmiennej _c typu byte wartości 1, operator ptr wymusza zmianę wielkości //operandu w tym przypadku na byte ponieważ zmienna c jest typu char, jest jednobajtowa

;

; {

; c=1;

;

mov byte ptr DGROUP:_c,1

//przypisanie do zmiennej _i wartości -1, operator ptr wymusza zmianę wielkości operandu w //tym przypadku na word ponieważ zmienna _i jest typu int

;

; i=-1;

;

mov word ptr DGROUP:_i,-1

//zapisanie adresu pierwszego elementu tablicy _Tabl do _ptr

;

; ptr=Tabl;

;

mov word ptr DGROUP:_ptr,offset DGROUP:_Tabl

//zapisanie do bx wartosci _ptr

//wpisanie do bx wartości 1

//zwiększenie adresu _ptr o 1

;

; *ptr++=1;

;

mov bx,word ptr DGROUP:_ptr

mov byte ptr [bx],1

inc word ptr DGROUP:_ptr

//zapisanie do bx wartosci _ptr

//wpisanie do bx wartości 2

//zwiększenie adresu _ptr o 1

;

; *ptr++=2;

;

mov bx,word ptr DGROUP:_ptr

mov byte ptr [bx],2

inc word ptr DGROUP:_ptr

//zapisanie do bx adresu _ptr

//zapisanie do al starszczej częsci znajdującej się w bx

//wpisanie al do zmiennej _c

//zmiejszenie adresu _ptr o 1

;

; c=*((ptr--)-1);

;

mov bx,word ptr DGROUP:_ptr

mov al,byte ptr [bx-1]

mov byte ptr DGROUP:_c,al

dec word ptr DGROUP:_ptr

//wpisanie wartości 87211 do unii do zmiennej utab[0].i

;

; utab[0].i =0x2211;

;

mov word ptr DGROUP:_utab,8721

//ponieważ utab[0].i jest dwubajtowe, następne przypisanie odbędzie się 2 bajty dalej w //_utab+2

;

; utab[1].c.l=0x33;

;

mov byte ptr DGROUP:_utab+2,51

//utab[1].c.l jest charem, jest jednobajtowe, więc kolejnene przypisanie następuje 1 bajt dalej //niż poprzednio _utab+3

;

; utab[1].c.h=0x44;

;

mov byte ptr DGROUP:_utab+3,68

;

; utab[2].c.l=0x55;

;

mov byte ptr DGROUP:_utab+4,85

;

; utab[2].c.h=0x66;

;

mov byte ptr DGROUP:_utab+5,102

//wskaźnik ptr pokazuje na pierwsze pole unii utab przekonwertowanej na char

;

; ptr=(char *)&utab[0];

;

mov word ptr DGROUP:_ptr,offset DGROUP:_utab

// do bx przypisywany jest adres wskaźnika _ptr, następnie do al wpisywany jest ten adres //większy o 1. Ponieważ zmienna int jest intem, należy przekonwertować ten bajt na słowo w ax. //Robi to komenda cbw. Po tej operacji można zapisać wartość z ax do zmiennej _i

;

; i=*(ptr+1);

;

mov bx,word ptr DGROUP:_ptr

mov al,byte ptr [bx+1]

cbw

mov word ptr DGROUP:_i,ax

// _ptr do ax, poprzez konwersje traktujemy ptr jako unie u1. Jako, że stosujemy konwersje na //u1, do adresu wskaźnika musimy dodac 2 w celu pokazania na następny element. Na końcu //przypisujemy tego ax do _ptr

;

; ptr = (char *) ((union u1 *)ptr+1);

;

mov ax,word ptr DGROUP:_ptr

add ax,2

mov word ptr DGROUP:_ptr,ax

// _ptr do bx, do c1 chcemy przypisac wskaźnik więc do al wpisujemy tylko młodszą część //adresu z bx bo _c1 jest charem, na koniec można wrzucić al do _c1. Została jeszcze //inkrementacja na sam koniec wskaźnika _ptr.

;

; c1=*ptr++;

;

mov bx,word ptr DGROUP:_ptr

mov al,byte ptr [bx]

mov byte ptr DGROUP:_c1,al

inc word ptr DGROUP:_ptr

// to samo co wyżej tylko ze zmienna _c2

;

; c2=*ptr++;

;

mov bx,word ptr DGROUP:_ptr

mov al,byte ptr [bx]

mov byte ptr DGROUP:_c2,al

inc word ptr DGROUP:_ptr

// przypisanie _utab do _uptr

;

; uptr = utab;

;

mov word ptr DGROUP:_uptr,offset DGROUP:_utab

// _uptr do bx, uptr jest wskaźnikiem na unie więc w celu pokazania na następny element //dodajemy 2, a następnie wpisuje tą wartość do _i

;

; i=(uptr+1)->i;

;

mov bx,word ptr DGROUP:_uptr

mov ax,word ptr [bx+2]

mov word ptr DGROUP:_i,ax

// ponieważ wskaźnik na unie jest dwubajtowy, przy jego zwiększaniu dodajemy do adresu 2.

;

; uptr++;

;

add word ptr DGROUP:_uptr,2

// to samo co wyzej

;

; i=(uptr+1)->i;

;

mov bx,word ptr DGROUP:_uptr

mov ax,word ptr [bx+2]

mov word ptr DGROUP:_i,ax

;

; }

;

//zdjecie ze stosu bp, bo main się kończy

pop bp

//powrót z maina

ret

//koniec procedury maina

_main endp

?debug C E9

?debug C FA00000000

//koniec deklaracji segmentu danych

_TEXT ends

//deklaracja segmentu danych

_DATA segment word public 'DATA'

s@ label byte

_DATA ends

//deklaracja segmentu kody

_TEXT segment byte public 'CODE'

_TEXT ends

// zmienne i funkcja main jest dostępna dla innych modułów

public _main

public _uptr

public _utab

public _ptr

public _Napis

public _Tabl

public _i

public _c2

public _c1

public _c

//przypisanie nazwy

_s@ equ s@

//koniec

end

Kod procesora dla modelu typu Large:

Różnice:

//_ptr i _uptr są wskaźnikami, jak widać poniżej w modelu Large są one podwójnymi słowami //czyli czterobajtowe.

_BSS segment word public 'BSS'

_ptr label dword

db 4 dup (?)

_utab label word

db 8 dup (?)

_uptr label dword

db 4 dup (?)

_BSS ends

//wywołanie funkcji main jest wywołaniem dalekim

assume cs:MAIN_TEXT

_main proc far

push bp

mov bp,sp

;

; {

; c=1;

;

mov byte ptr DGROUP:_c,1

;

; i=-1;

;

mov word ptr DGROUP:_i,-1

//Wpisanie do młodszej części ptr wartości ds, oraz wpisanie do starszej części _Tabl

;

; ptr=Tabl;

;

mov word ptr DGROUP:_ptr+2,ds

mov word ptr DGROUP:_ptr,offset DGROUP:_Tabl

//przeniesienie _ptr do pary rejestrów es:bx, bo w modelu large wskaźniki są 4 bajtowe a bx jest //dwu. Wpisanie do tej pary rejestrów wartości 1 oraz inkrementacja _ptr

;

; *ptr++=1;

;

les bx,dword ptr DGROUP:_ptr

mov byte ptr es:[bx],1

inc word ptr DGROUP:_ptr

;

; *ptr++=2;

;

les bx,dword ptr DGROUP:_ptr

mov byte ptr es:[bx],2

inc word ptr DGROUP:_ptr

//przeniesienie _ptr do pary rejestrów es:bx, przeniesienie do al adresu o 1 mniejszego, //przypisanie _c wartości al oraz dekrementacja ptr

;

; c=*((ptr--)-1);

;

les bx,dword ptr DGROUP:_ptr

mov al,byte ptr es:[bx-1]

mov byte ptr DGROUP:_c,al

dec word ptr DGROUP:_ptr

;

; utab[0].i =0x2211;

;

mov word ptr DGROUP:_utab,8721

;

; utab[1].c.l=0x33;

;

mov byte ptr DGROUP:_utab+2,51

;

; utab[1].c.h=0x44;

;

mov byte ptr DGROUP:_utab+3,68

;

; utab[2].c.l=0x55;

;

mov byte ptr DGROUP:_utab+4,85

;

; utab[2].c.h=0x66;

;

mov byte ptr DGROUP:_utab+5,102

//wpisanie do młodszej częsci wskaźnika ds, oraz zapisanie _utab do starszej częsci.

;

; ptr=(char *)&utab[0];

;

mov word ptr DGROUP:_ptr+2,ds

mov word ptr DGROUP:_ptr,offset DGROUP:_utab

//przeniesienie _ptr do es:bx, przeniesienie do al wartościa adresu o 1 większego, konwersja al //na ax oraz wpisanie tej wartości do _i

;

; i=*(ptr+1);

;

les bx,dword ptr DGROUP:_ptr

mov al,byte ptr es:[bx+1]

cbw

mov word ptr DGROUP:_i,ax

//ax-mlodsza czesc wskaznika, bx- starsza czesc, dodanie do dx wartosci 2, wpisanie do //mlodszej czesci ponownie ax oraz do starszej dx.

;

; ptr = (char *) ((union u1 *)ptr+1);

;

mov ax,word ptr DGROUP:_ptr+2

mov dx,word ptr DGROUP:_ptr

add dx,2

mov word ptr DGROUP:_ptr+2,ax

mov word ptr DGROUP:_ptr,dx

// _ptr do es:bx, przeniesienie jednego bajtu es:bx do al, wskazujacego na poczatek _ptr, //zapisanie do _c11 oraz inkrementacja _ptr

;

; c1=*ptr++;

;

les bx,dword ptr DGROUP:_ptr

mov al,byte ptr es:[bx]

mov byte ptr DGROUP:_c1,al

inc word ptr DGROUP:_ptr

;

; c2=*ptr++;

;

les bx,dword ptr DGROUP:_ptr

mov al,byte ptr es:[bx]

mov byte ptr DGROUP:_c2,al

inc word ptr DGROUP:_ptr

//przypisanie do starszej czesci wartości _utab

;

; uptr = utab;

;

mov word ptr DGROUP:_uptr+2,ds

mov word ptr DGROUP:_uptr,offset DGROUP:_utab

// przypisanie _uptr do es:bx, do ax wpsianie wartosci adresu o 2 wiekszego, wskazujacego na //nastepny element, zapisanie ax do _i.

;

; i=(uptr+1)->i;

;

les bx,dword ptr DGROUP:_uptr

mov ax,word ptr es:[bx+2]

mov word ptr DGROUP:_i,ax

//wskazywanie na nastepny element w pamieci

;

; uptr++;

;

add word ptr DGROUP:_uptr,2

;

; i=(uptr+1)->i;

;

les bx,dword ptr DGROUP:_uptr

mov ax,word ptr es:[bx+2]

mov word ptr DGROUP:_i,ax

;

; }

;

pop bp

ret

_main endp



Wyszukiwarka

Podobne podstrony:
Projekt Inż, Wstęp, Laboratorium programowania niskopoziomowego
pskSCIAGA, podstawy programowania niskopoziomowego
Programowanie Niskopoziomowe 3, Politechnika Lubelska, Studia, semestr 5, Sem V, Nowy folder
Programowanie Niskopoziomowe Sprawozdanie nr.1-2, Informatyka
Programowanie Niskopoziomowe Sprawozdanie nr.3, Informatyka
programowanie niskopoziomowe id Nieznany
Programowanie Niskopoziomowe Sprawozdanie nr.7, Informatyka
Programowanie niskopoziomowe
programowanie niskopoziomowe spr4
programowanie niskopoziomowe spr4
Programowanie Niskopoziomowe Sprawozdanie nr.6, Informatyka
Programowanie Niskopoziomowe Sprawozdanie nr.4-5, Informatyka
Profesjonalne programowanie Czesc 2 Mysl niskopoziomowo pisz wysokopoziomowo propr2
Profesjonalne programowanie Czesc 2 Mysl niskopoziomowo pisz wysokopoziomowo propr2
Profesjonalne programowanie Czesc 2 Mysl niskopoziomowo pisz wysokopoziomowo propr2
Profesjonalne programowanie Czesc 2 Mysl niskopoziomowo pisz wysokopoziomowo

więcej podobnych podstron