Nowe posty

Autor Wątek: [asembler] kilka pytan i prosty program  (Przeczytany 5123 razy)

Hellbike

  • Gość
[asembler] kilka pytan i prosty program
« dnia: 2009-03-15, 12:56:14 »
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?

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3056
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
[asembler] kilka pytan i prosty program
« Odpowiedź #1 dnia: 2009-03-15, 17:13:03 »
Problem jest w niejednoznacznej składni w różnych asemblerach (w znaczeniu programach tłumaczących plik asm na obj).

Składnia pierwsza (występuje w Twoich przykładach):
mov eax, ZMIENNA - załadowanie do eax zawarości komórki o adresie ZMIENNA
mov eax, offset ZMIENNA - załadowanie do eax adresu komórki ZMIENNA

Składnia druga:
mov eax,[ZMIENNA] - załadowanie do eax zawarości komórki o adresie ZMIENNA
mov eax, ZMIENNA - załadowanie do eax adresu komórki ZMIENNA

W większości "zwykłych" procesorów rejestry nie mają adresów. W mikrokontrolerach co najmniej rodzin MCS51 i AVR (z tymi pracowałem) rejestry są widoczne w przestrzeni adresowej i można się dostać do nich zarówno przez adresowanie pamięci jak i adresowanie rejestrowe.

Co do położenia zmiennej w dowolnym miejscu pamięci - poczytaj o ochronie i segmentacji pamięci. W ogólności - to system przydziela ci kawałek pamięci (np przez malloc) i pilnuje, czy nie wykraczas poza jego granice. Nie masz wpływu, gdzie w pamięci fizycznej znajdzie się zaalokowany blok. Co gorsza - przy braku pamięci system może zrzucić twój blok do swapa i później odtworzyć w zupełnie inym miejscu pamięci fizycznej (dzięki segmentacji twój program nie zauważy zmiany).

Na koniec - możesz sprawić, że program będzie działał na pamięci całkowicie z pominięciem OSa tylko w ten sposób, że będzie pracował w tzw. "Ringu 0", czyli de facto z tymi samymi uprawnieniami co system operacyjny. Lepiej będzie jednak pracować przy wsparciu OSa, pisząc własny moduł jądra.
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

RyszardLin

  • Gość
[asembler] kilka pytan i prosty program
« Odpowiedź #2 dnia: 2009-03-15, 22:07:11 »
Cytat: pkraszewski
mov eax, ZMIENNA - załadowanie do eax zawarości komórki o adresie ZMIENNA
mov eax, offset ZMIENNA - załadowanie do eax adresu komórki ZMIENNA
Witam

  Tak na moje - pierwsza linia ładuje zawsze adres (dokładniej, przesunięcie względem segmentu w którym znajduje się dana zmienna) - a instrukcja mov eax, dword ptr ZMIENNA - ładuje 32bity z pamięci.
  A druga instrukcja - ładuje przesunięcie w segmencie danej zmiennej.

  UWAGA: Dana zmienna nie musi się znajdować w segmencie danych!!! na który wskazuje rejestr DS - brany domyślnie.

 Pozdro