Jak odczytac bity kodu operacji? (Asm)

0

Potrzebuję mianowicie odczytać zawartość pola mod i nie wiem za bardzo jak to uczynić.

Pozdr.

0

Podobno na Assemblerze coś tam się znam, ale nie mam <font color="green">zielonego</span> pojecia o co pytasz :|.

Co to jest pole "mod"???

0

Juz mówie:

Podstawowy format instrukcji w procesorach Pentium wygląda następująco:

PIERWSZY BAJT: kod operacji d w
DRUGI BAJT: mod reg r/m
TRZECI BAJT(tylko w trybie 32-bit): ss index base
KOLEJNE BAJTY pole przesunięcia

I tak:
kod operacji - 6 bitów; określa czynności wykonywane przez rozkaz

bit d - określa do którego z operandów zostanie przesłany wynik operacji
0 - do obiektu wskazywanego przez pole r/m
1 - do obiektu wskazywanego przez pole reg

bit w - określa rozmiar operandów na których wykonywana jest operacja
0 - operacja 8-bitowa
1 - operacja 16- lub 32-bitowa

pole mod - 2 bity - określa długość(liczbę bajtów) pola przesunięcie
00 - 0 bajtów; pole przesunięcie nie występuje
01 - 1 bajt
10 - 2 bajty(tryb 16-bit) lub 4 bajty(tryb 32-bit)
11 - dwa rejestry (patrz pole r/m)

pole reg - 3 bity - identyfikuje rejestr procesora w który znajduje sie jeden z operandów

pole r/m - 3 bity - pole to zawiera kod drugiego rejestru(gdy mod = 11) lub określa sposób obliczania adresu efektywnego(gdy mod <> 11)

Trzeci bajt (tzw. bajt SIB) - występuje tylko w trybie 32-bitowym; opisuje sposób obliczania adresu efektywnego

Pole przesunięcia - określa przesunięcie względem początku segmentu, służy do wyznaczania adresu efektywnego

Instrukcje niesterujące(tryb 16-bit) - zwykle 3 lub 4 bajty - trzeci i czwarty bajt to odpowiednio młodsza i starsza część pola przesunięcie.
Kilka przykładów(wszystkie w trybie 16-bit):

mov dl, [si]+7 100010 1 0 01 010 100 00000111 00000000

add bx, [45A1h] 000000 1 1 00 011 110 10100001 01000101

sub dx, 5 100000 1 1 11 101 010 00000101 00000000

0

Przyznam, że zaciekawił mnie Twój post. Nie znałem znaczenia poszczególnych bitów.

No a co do pytania, to wydaje mi sie bardzo proste, ale pytanie: czy chcesz odczytać pole mod dla aktualnej instrukcji, czy dla dowolnej wskazanej?

Jeśli np. pod zmienną przes mamy adres instrukcji do analizy, to ja bym rozwiązał to tak:

mov bx,przes
mov al,[bx+1]
shr al,6

Teraz w AL masz dwa bity - pole mod.

0

Co wy się tak uparliście na te mody? Na binboyu jest takie samo pytanie.
A co do budowy instrukcji to jest w dokumencacji Intela (chyba 2 część).

//Trzeba ją mieć :-P - m.M

0

Ok. Ale jak znalezc adres instrukcji?
Jak np. pobrać adres instrukcji sub dx, 5 występującej w jakimś programie? Domyślam sie ze trzeba jakoś to pobrać z IP, ale jak?

0

Znów nie do końca jarzę.
Masz przykład:

mov ax,5
add bx,ax
instr:
shr bx,cl
xor bx,ax

no to instr jest adresem instrukcji shr bx,cl

0

No tak..., ale czy można pobrać jakoś adres instrukcji shr bx,cl nie tworząc przed nią etykiety?
I jeszcze drugie pytanie - jak odczytać zawartość rejestru IP?

0

No tak..., ale czy można pobrać jakoś adres instrukcji shr bx,cl nie tworząc przed nią etykiety?

Niby jak - skąd będziesz wiedział, gdzie ona leży? No chyba, że szukasz specyficznej instrukcji, to możesz przeszukać segment kodu w poszukiwaniu odpowiedniego ciągu bajtów, ale zawsze możesz trafić na taką samą w innym miejscu. A poza tym - jak masz ten ciąg bajtów, to po co go szukać, skoro go już masz :-) - przeanalizuj go :>.

I jeszcze drugie pytanie - jak odczytać zawartość rejestru IP?

call $+3  ;16bit
pop ax     ;ax zawiera IP siebie (czyli instrukcji pop ax)
0

No to wyloze teraz kawe na lawe :-)

Pisze taki program:

W przypadku wystąpienia nadmiaru przy dzieleniu (rozkazy DIV i IDIV) generowany jest wyjątek procesora, przy czym na stosie zapisywany ślad wskazujący położenie rozkazu DIV lub IDIV.
Napisać fragment programu w asemblerze, który wznowi wykonywanie przerwanego programu, pomijając rozkaz dzielenia, który spowodował wyjątek. Przyjąć, że procesor pracuje w trybie 16-bitowym.

Zamierzam to zrobić tak:
-zmienic procedurę obsługi, tak aby nie było w niej wyjscia do systemu.
-zwiększyć IP znajdujący się na stosie o ilość bajtów zajmowaną przez instrukcję DIV(do tego jet potrzebne wlasnie pole mod)
-wrocić do wykonywania programu poprzez odtworzenie stosu

To jest na razie taki wstepny projekt jaki mi przyszedł do głowy.
Mam jeszcze jedno pytanko:
Jak moge zwiększyć IP?

0

Jak moge zwiększyć IP?

Nie da się bezpośrednio.
Chcesz zwiększyc aktualne IP o 4?

jmp $+4
0

No k*** ja już nie mogę.
Takie samo pytanie na BHP zadałeś. Piote zgadza się?
Skoro tam już otrzymujesz odpwiedź, to odpuść sobie tutaj. Wysłuchaj, co tam mają dla ciebie do powiedzenia i tam ciągnij ten wątek, a nie tak jak teraz to jest tak:

  1. Zadajesz pytanie na BHP.
  2. Ktoś odpowiada na to pytanie na BHP (zazwyczaj snaj)
  3. Zadajesz pytanie na 4p
  4. Ktoś odpowiada na to pytanie na 4p.
  5. Pytasz dalej na BHP i tam ktoś odpowiada, a potem to samo powtarzasz na 4p.
    Czasem jest tak, że na jednym forum pytasz o jeden fragment, a na drugim o drugi.
    Dochodzi do tego, że ani na jednym, ani na drugim nie wiadomo o co chodzi.
    Jak już masz odpowiedź na BHP to ciągnij tam dyskusję. Jeżeli uznasz, że tam nikt nie jest w stanie na to odpowiedzieć, to zadaj tutaj, lub odwrotnie, jak zaczynasz tutaj, to ciągnij dyskusję dalej.
    A jeżeli już zadajesz pytanie na jednym i drugim forum, to opisz od razu dokładnie całe zadanie i fragment, który sprawia problem, a nie fragment tutaj i fragment tam oraz wrzuć na jedno i drugie forum pytanie. Jak na jednym już rozpocznie się dyskusja i twoim zdaniem posypią się satysfakcjonujące odpowiedzi, to kontynuuj na jednym forum. :-[

Uff... Ulżyło mi. Jeżeli przez przypadek pojechałem po niewinnych, to wybaczcie.

Teraz dalej. Marooned: dokumentację Intela możesz ściągnąć ze strony Intela (choć na pewno to masz :) ).
Tam w rozdziale 2 od razu na początku jest schemat budowy instrukcji. Problem w tym, że przedstawiony schemat przez autora tego wątku jest prawdziwy jedynie dla pewnych instrukcji.
Tzn. problem jest taki, że jeżeli jest użyte np. wymuszenie segmentu, to mamy prefix.
Znacznie gorzej jest w przypadku kodu 32-bitowego. Tam prawie każda instrukcja wykorzystująca adresy lub rejestry o niedomyślnym rozmiarze ma prefix z oznaczeniem instrukcji dla wersji 32-bitowej (co jest bardzo częste).

0

Tak to ja. Ale na BHP to nie ja. Czytalem to na BHP i gosc powiedzial ze rozwalil to zadanie - podal nawet linka - tyle ze tam nic nie ma! Uznalem wiec ze pisanie takiego samego tematu na BHP nie bedzie mialo sensu wiec temat jest w calosci rozwinięty tutaj.

Ale swoją drogą niezły z Ciebie Sherlock ;-) :-)

Pozdr.

0

Hihi Dryobates trza cos lyknac na odprezenie ;) polecalbym pewien trunek
ale poniewaz moga to czytac niepelnoletni ;) i jeszcze podpadne pod paragrafy :(
to nie podam jego nazwy :)

A tak wracajac do tego tematu to najwidoczniej wlasnie Piote skonczyl z BHP
(zwazywszy na date postu tam i daty tutaj ;) ) a jak widac to nie on :).
Swoja droga ostatnio coraz wiecej osob jedzie na dwa fronty :)

  • pisze takiego samego posta na 4p i BHP rownolegle !!
0

Dobra, poniosło mnie.
Nie mam nic przeciwko, jak ktoś pisze równolegle na jednym i drugim, ale jak widzę fragment na jednym i fragment na drugim i tego samego dotyczy, to jak dla mnie to jest zbędne zaśmiecanie forum.
Dobra. Koniec z tym i przepraszam, za taki OT w tym wątku.

A co do napoju... Fundujesz? ;)

0

Sprobuj tak:

  1. na stosie masz juz CS i IP wskazujace na rozkaz DIV - wiec nie musisz korzystac
    z IP zeby sie do niego dostac !! Pobierasz ze stosu IP (ale nie pop bo SP zmodyfikujesz )!!
    do jakiegos rejestru(ktorym mozna adresowac ;) np. mov bp,sp ; mov bx, word ptr [bp+2] ) i cs:[bx+1] i masz bajt w ktorym jest MOD !!
  2. interpretujesz MOD i w zaleznosci od jego wartosci do IP na stosie dodajesz
    odpowiednia liczbe !!
  3. z procedury obslugi 00h powracasz IRET ktory pobiera ze stosu IP, CS i flagi
    i juz masz IP wskazujacy offset nastepnego rozkazu po DIV.
  4. Uwazaj na modyfikowane rejestry w procedurze obslugi przerwania i je oddtworz
    przy wychodzeniu, nie zostaw zadnej wartosci na stosie bo SP przy wychodzeniu
    IRET musi wskazywac na IP.
  5. Nie jestem tylko pewny czy przy 00h na stos przed CS i IP odkladane sa tez flagi ?! Bo jesli nie to IRET nic nie zdziala wiec zapewne trzeba zastosowac RET - ale dalej wszystko powyzej dziala !

PS. Mam nadzieje ze nie walnalem jakiejs glupoty :)
PS2. Dryobates napoj orzezwiajacy ;) to w padzierniku podpiernicze u kumpla
- on zawsze ma zapas ;)

0

Napisalem taka prosedure obslugi:

Obsl_dziel PROC

pop bx                ;zdjęcie ze stosu wartości IP
mov al,[bx+1]     
shr al,6                ;znalezienie wartości pola mod (teraz jest w al)

cmp al, byte ptr 0
je dwa
cmp al, byte ptr 3
je dwa
cmp al, byte ptr 1
je trzy
cmp al, byte ptr 2
je cztery

dwa:
    mov cx,2
    jmp dalej

trzy:
    mov cx,2
    jmp dalej

cztery:
    mov cx,2
    jmp dalej

dalej:
    add bx, cx        ;dodanie do starej zawartosci IP ilosci bajtow DIVa
push bx                ;zapamiętanie na stosie nowej wartości IP

iret                       ;powrót do wykonywanego programu
Obsl_dziel ENDP

Na razie wszystko dziala jak powinno :)
Dzieki za pomoc.

0

Piote: jak działa, to byłbym wdzięczny, za wrzucenie tego do FAQ w dziale Assembler.
snaj: trzymam za słowo ;)

0

Dla niewtajemniczonych ;) moj opis slowny to wlasciwie = implementacja Piote hihi on to sam
wymyslil i ja to tez sam wymyslilem wow coz za zbieg okolicznosci :>

AHA WAZNE !!!

Piote jestes pewny ze to dziala !! Nie podoba mi sie ta linijka :
<cpp>
mov al,[bx+1]
<cpp>
Dla BX domyslnym rejestrem segmentowym jest DS !!!! Wiec pradopodobnie
to przypadek ze Ci program dobrze dziala bo tak naprawde pobierasz
bajt z segmentu danych ds:[bx+1] !!!! Powinno byc raczej :
<cpp>
mov al,cs:[bx+1]
<cpp>
I dopiero teraz jest OK ?! Sprawdz dokladnie - uwzgledniajac rozne
dlugosci rozkazu !!!!

0

OK - jeszcze to przetestuje. I jak bedzie dzialalo to wrzuce do FAQ. Tyle ze we wtorek, bo wyjezdzam, a za 20 min ucieka mi pociaąg!

0

Miales racje, Snaj. Poza tym program wymaga jeszcze dopracowania.

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