Potrzebuję mianowicie odczytać zawartość pola mod i nie wiem za bardzo jak to uczynić.
Pozdr.
Potrzebuję mianowicie odczytać zawartość pola mod i nie wiem za bardzo jak to uczynić.
Pozdr.
Podobno na Assemblerze coś tam się znam, ale nie mam <font color="green">zielonego</span> pojecia o co pytasz :|.
Co to jest pole "mod"???
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
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.
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
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?
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
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?
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)
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?
Jak moge zwiększyć IP?
Nie da się bezpośrednio.
Chcesz zwiększyc aktualne IP o 4?
jmp $+4
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:
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).
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.
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 :)
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? ;)
Sprobuj tak:
PS. Mam nadzieje ze nie walnalem jakiejs glupoty :)
PS2. Dryobates napoj orzezwiajacy ;) to w padzierniku podpiernicze u kumpla
- on zawsze ma zapas ;)
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.
Piote: jak działa, to byłbym wdzięczny, za wrzucenie tego do FAQ w dziale Assembler.
snaj: trzymam za słowo ;)
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 !!!!
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!
Miales racje, Snaj. Poza tym program wymaga jeszcze dopracowania.