[asembler] kilka pytan i prosty program

0

Rozumiem ze zadeklarowane zmienne zostaja utworzone w pamieci ram, a sam program 'pamieta' ich ardesy.
Rejestry moga przechowywac pewna wartosc - ktora moze byc rownie dobrze adresem, jak i wartoscia przechowywanym adresem (co dla procesora nie ma znaczenia).
jedyna operacja, jaka moge wykonac na pamieci ram, to zapisanie tam okreslonych bajtow - tzn, nie moge w pamieci ram wykonac algorytmu sumy logicznej, czy czegokolwiek innego - jedyne co moge zrobic, to zapisac okreslone juz dane (np. 00010111). do wykonywania operacji logicznych/arytmetycznych musze skopiowac pewne dane do rejestru procesora, i operowac na rejestrach.
w ksiazce przeczytalem, ze odnoszac sie zmiennej w pamieci ram, napisanie jej nazwy w nawiasach kwadratowych powoduje odczytanie jej wartosci, a bez nawiasow - adresu. w innej ksiazce mam nastepujacy przyklad, programu dodajcego dwie liczby:

       
.data
      VARA DW 17
      VARB DW 35
.stack 100h
.code
      mov ax, @data
      mov ds, ax
      mov ax, VARA
      add ax, VARB

w .code pierwsze dwie linijki sa dla mnie malo zrozumiale(wiem jaki jest cel ich istnienia, ale na przykladach pod linuksa nie musze tego umieszczac, dlaczego?), a pozostale powinno kolejno umieszczac adres VARA w rejestrze ax, a nastepnie zwiekszyc wartosc ax o wartosc adresu VARB. dlaczego nie uzyto tutaj nawiasow klamrowych?

chcialem napisac program dodajacy dwie liczby i wyswietlajacy wynik pod linuksa (idac za przykladem powyzej, bez nawiasow klamrowych).

format ELF executable           ; typ pliku
entry _start                    ; punkt startu programu
segment readable executable     ; początek sekcji kodu
_start:
mov eax, number1
add eax, number2
mov ebx, 1
mov ecx, eax 
mov edx, 1
mov eax, 4
int 80h
segment readable writeable      ; początek sekcji danych.
number1 dw 10
number2 dw 15

exc ma zawaierac adres danych, ktore chce wyswietlic. a co jesli dane te sa w rejestrze? czy mozna w ogole mowic o adresie rejestru? jesli tak, to jak go przekazac do innego rejestru? czy musze najpierw zawartosc adresu przekazac do zmiennej?
i co z wyswietleniem wartosci? chcac wyswietlic wartosc 17, czy musze najpierw napisac program konwertujacy 17 do 17 w postaci ASCII?

oraz dodatkowe pytanie odnosnie zmiennych - czy tworzac zmienna moge dokladnie okreslic jej polozenie w pamieci ram?
jesli tak, to czy pozniej moge zapisywac wartosci do konkretnej komorki, nie odnoszac sie do nazw zmiennych?
jesli tak, to czy moge zmusic procesor do dzialania "nad" systemem operacyjnym? nie wiem do konca jak to dziala, ale zakladam ze program uruchamiany kontrolowany jest przez system operacyjny, ktory moze blokowac dostep do pewnych elementow pamieci. Czy moge sprawic, aby procesor zaczal wykonywac operacje bezposrednio na pamieci ram, bez zadnej komunikacji z systemem operacyjnym?

0

dlaczego nie uzyto tutaj nawiasow klamrowych?

Właściwie są 2 przypadki traktowania adresów i zmiennych. To jest zależne od składni kompilatora asemblera. Najczęściej stosuje się składnię.
mov ax, VARA ; do ax ładowany jest adres zmiennej
mov ax, [VARA] ; do ax leci wartość zmiennej
Jednak są też kompilatory o trochę innej składni gdzie stosuje się takie coś:
mov ax, offset VARA ; do ax adres
mov ax, VARA ; do ax wartość zmiennej
Dla przykładu mogę podać, że pierwszy przedstawiony rodzaj składni jest stosowany w kompilatorze NASM, a drugi w MASM. Więc czytając kod najlepiej wiedzieć jaki ktoś używa kompilator lub na oko to ocenić (czy są nawiasy czy słowo offset). Jeżeli sam używasz jakiegoś kompilatora to musisz znać jego składnię i wiedzieć jak zapisywać adresy.

exc ma zawaierac adres danych, ktore chce wyswietlic. a co jesli dane te sa w rejestrze? czy mozna w ogole mowic o adresie rejestru? jesli tak, to jak go przekazac do innego rejestru? czy musze najpierw zawartosc adresu przekazac do zmiennej?
i co z wyswietleniem wartosci? chcac wyswietlic wartosc 17, czy musze najpierw napisac program konwertujacy 17 do 17 w postaci ASCII?

Ta funkcja przerwania wypisuje na ekran ciąg znaków ASCII. W ecx jest adres pamięci, a w edx ilość bajtów/znaków które chcesz wyświetlić. Nie da się w żaden sposób zaadresować w ten sposób rejestru procesora. No i nie można za pomocą tej funkcji wyświetlić wartości liczbowej przechowywanej przykładowo przez rejestr. Musisz ją przeliczyć i zapisać w formie znaków ASCII gdzieś w pamięci, ale to nie jest trudne i na pewno na twoje możliwości.

oraz dodatkowe pytanie odnosnie zmiennych - czy tworzac zmienna moge dokladnie okreslic jej polozenie w pamieci ram?

Po wgraniu programu do pamięci każda nazwa zmiennej właściwie staje się już jej adresem. Bezpośrednie odwoływanie się do jakiejkolwiek pamięci w asemblerze jest bardzo proste. Przykładowo chcesz wczytać do ax słowo z pod adresu pamięci 127. To nic prostszego:
mov bx, 127
mov ax, [bx]
A ta pamięć na pewno nie należy do pamięci programu.

jesli tak, to czy pozniej moge zapisywac wartosci do konkretnej komorki, nie odnoszac sie do nazw zmiennych?
jesli tak, to czy moge zmusic procesor do dzialania "nad" systemem operacyjnym? nie wiem do konca jak to dziala, ale zakladam ze program uruchamiany kontrolowany jest przez system operacyjny, ktory moze blokowac dostep do pewnych elementow pamieci.

Odwoływać się do dowolnej pamięci możesz tak jak napisałem powyżej. Jednak swobodny dostęp do pamięci jest zabroniony z innych powodów niż znajomość adresów. Dzisiejsze systemy takie jak Windows czy Linux pracują w trybie zwanym chronionym (protected mode), który korzysta z dodatkowych rejestrów i zabezpieczeń procesora. W odpowiednim rejestrze jest zapisany poziom uprawnień jaki posiada w danym momencie wykonywany kod. A po przez system stronicowania pamięci ustala się obszary pamięci do których można się dostać posiadając pewną wartość uprawnień. Ogólnie program posiada najniższy poziom uprawnień i ma prawo do używania jedynie własnej pamięci (ogólnie swoich zmiennych). Jeżeli odwoła się do pamięci systemowej (przykładowy adres 127) to zostanie od razu wywołane przez CPU odpowiednie przerwanie i system zostanie poinformowany o nieprawidłowym działaniu programu. Co w wyniku da prawdopodobnie jego zamknięcie i usunięcie z pamięci przez system.
Systemem który umożliwiał swobodny dostęp do pamięci był DOS, ale to stare dzieje.

Czy moge sprawic, aby procesor zaczal wykonywac operacje bezposrednio na pamieci ram, bez zadnej komunikacji z systemem operacyjnym?

Program właściwie realizuje operacje na pamięci nie odwołując się do systemu operacyjnego. Przykładowa instrukcja:
mov [bx], ax
Operuje bezpośrednio na pamięci o adresie zapisanym w bx. System kontroluje jedynie przydział pamięci po przez zarezerwowanie jej przy wgrywaniu twojego programu do pamięci lub przy alokowaniu dynamicznym przez malloc czy jakąś inną funkcje systemową. W ten sposób system wydziela część pamięci dla programu, a sam program działa bezpośrednio na tej pamięci bez użycia systemu operacyjnego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1