Jak obliczyć Adres Docelowy skoku i Adres Docelowy gałęzi?

Jestem nowy w Assembly language . Czytałem o architekturze MIPS i utknąłem z adresem docelowym skoku i adresem docelowym gałęzi i Jak obliczyć każdy z nich.

Author: Peter Cordes, 2011-08-05

4 answers

1. Obliczanie Adresu Oddziału

W MIPS Branch instrukcja ma tylko 16 bitów przesunięcia do określenia następnej instrukcji. Potrzebujemy rejestru dodanego do tej 16-bitowej wartości, aby określić następną instrukcję i ten rejestr jest faktycznie sugerowany przez architekturę. Jest to PC register, ponieważ PC jest aktualizowany (PC+4) podczas cyklu pobierania tak, że przechowuje adres następnej instrukcji. Ograniczamy również odległość gałęzi do -2^15 to +2^15 - 1 instrukcji z (instrukcji po )gałęzi Instrukcja. Jednak nie jest to prawdziwy problem, ponieważ większość oddziałów i tak jest lokalnych.

Więc krok po kroku:

  • znak rozszerza 16-bitową wartość offsetu, aby zachować jej wartość.
  • pomnóż otrzymaną wartość przez 4. Powodem tego jest to, że jeśli zamierzamy rozgałęziać jakiś adres, a komputer jest już wyrównany w słowie, to natychmiastowa wartość musi być również wyrównana w słowie. Nie ma jednak sensu, aby natychmiastowe słowo było dopasowane, ponieważ marnowalibyśmy niskie dwa bity, zmuszając je do 00.
  • teraz mamy adres 32 bitowy. Dodaj tę wartość do PC + 4 i będzie to twój adres oddziału.

Obliczanie adresu oddziału


2. Obliczanie Adresu Skoku

Dla instrukcji skoku Mips ma tylko 26 bitów do określenia położenia Skoku. Poza tym skoki są w stosunku do PC w MIPS. Podobnie jak branch, wartość natychmiastowego skoku musi być dopasowana do słów;dlatego musimy pomnożyć adres 26 bitowy przez cztery.

Jeszcze raz krok po kroku Krok:

  • pomnóż 26-bitową wartość przez 4.
  • ponieważ przeskakujemy względem wartości komputera, połącz pierwsze cztery bity wartości komputera na lewo od naszego adresu skoku.
  • adres wynikowy jest wartością skoku.

Innymi słowy, zastąp dolne 28 bitów PC niższymi 26 bitami pobrana Instrukcja przesunięta w lewo o 2 bity.

Tutaj wpisz opis obrazka

Źródło: Bilkent University CS 224 kurs slajdy

 57
Author: emre nevayeshirazi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-23 17:13:43

Zazwyczaj nie musisz się martwić o ich obliczanie, ponieważ twój asembler (lub linker) zajmie się poprawnym obliczaniem. Załóżmy, że masz małą funkcję:


func:
  slti $t0, $a0, 2
  beq $t0, $zero, cont
  ori $v0, $zero, 1
  jr $ra
cont:
  ...
  jal func
  ... 

Podczas tłumaczenia powyższego kodu na binarny strumień instrukcji asemblera (lub linkera, jeśli po raz pierwszy zmontowano go do pliku obiektowego) zostanie określone, gdzie w pamięci będzie znajdować się funkcja (na razie zignorujmy kod niezależny od pozycji). Gdzie w pamięci będzie się znajdować jest zazwyczaj określone w ABI lub podane do ciebie jeśli używasz symulatora (np. SPIM który ładuje kod na 0x400000 - Uwaga link zawiera również dobre wyjaśnienie procesu).

Zakładając, że mówimy o przypadku SPIM i nasza funkcja jest pierwsza w pamięci, slti Instrukcja będzie rezydować w 0x400000, beq w 0x400004 i tak dalej. Już prawie jesteśmy! Dla instrukcji beq adres docelowy gałęzi to cont (0x400010) patrząc na MIPS Instrukcja reference widzimy, że jest zakodowana jako 16-bitowa, podpisana bezpośrednio w stosunku do następnej instrukcji (podzielona przez 4, ponieważ wszystkie instrukcje muszą znajdować się na wyrównanym 4-bajtowym adresie).

Czyli:

Current address of instruction + 4 = 0x400004 + 4 = 0x400008
Branch target = 0x400010
Difference = 0x400010 - 0x400008 = 0x8
To encode = Difference / 4 = 0x8 / 4 = 0x2 = 0b10

Kodowanie beq $t0, $zero, cont

0001 00ss ssst tttt iiii iiii iiii iiii
---------------------------------------
0001 0001 0000 0000 0000 0000 0000 0010

Jak widzisz możesz rozgałęziać się do wewnątrz -0x1fffc .. 0x20000 bajtów. Jeśli z jakiegoś powodu musisz skoczyć dalej, możesz użyć trampoliny (bezwarunkowego skoku do rzeczywistego celu umieszczonego w danym limit).

adresy docelowe przeskoków są, w przeciwieństwie do adresów docelowych gałęzi, zakodowane przy użyciu adresu absolutnego (ponownie podzielonego przez 4). Ponieważ kodowanie instrukcji używa 6 bitów dla kodu opcode, pozostawia to tylko 26 bitów dla adresu (efektywnie 28 biorąc pod uwagę, że 2 ostatnie bity będą równe 0), dlatego 4 bity najbardziej znaczących bitów rejestru PC są używane podczas tworzenia adresu (nie ma znaczenia, chyba że zamierzasz przeskoczyć 256 MB granice).

Zwracając do powyższego przykładu kodowanie dla jal func to:

Destination address = absolute address of func = 0x400000
Divided by 4 = 0x400000 / 4 = 0x100000
Lower 26 bits = 0x100000 & 0x03ffffff = 0x100000 = 0b100000000000000000000

0000 11ii iiii iiii iiii iiii iiii iiii
---------------------------------------
0000 1100 0001 0000 0000 0000 0000 0000

Możesz to szybko zweryfikować i pobawić się różnymi instrukcjami, używając tegoasemblera MIPS online , na który natknąłem się (zauważ, że nie obsługuje wszystkich opcodów, na przykład slti, więc po prostu zmieniłem to na slt tutaj):

00400000: <func>    ; <input:0> func:
00400000: 0000002a  ; <input:1> slt $t0, $a0, 2
00400004: 11000002  ; <input:2> beq $t0, $zero, cont
00400008: 34020001  ; <input:3> ori $v0, $zero, 1
0040000c: 03e00008  ; <input:4> jr $ra
00400010: <cont>    ; <input:5> cont:
00400010: 0c100000  ; <input:7> jal func
 15
Author: user786653,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-05 09:36:57

Dla małych funkcji takich jak ta, możesz po prostu liczyć ręcznie, ile jest przeskoków do celu, z instrukcji pod instrukcją branch. Jeśli odgałęzia się do tyłu, niech liczba przeskoków będzie ujemna. jeśli liczba ta nie wymaga wszystkich 16 bitów, to dla każdej liczby na lewo od najbardziej znaczącej z Twojej liczby hop, zrób je 1, jeśli liczba hop jest dodatnia, zrób je wszystkie 0, ponieważ większość gałęzi jest blisko ich celów, oszczędza to dużo dodatkowej arytmetyki dla większość przypadków.

  • chris
 0
Author: kiwicomb123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-24 21:35:01

Myślę, że trudno byłoby je obliczyć, ponieważ Adres Docelowy gałęzi jest ustalany w czasie wykonywania, a przewidywanie odbywa się w sprzęcie. Gdybyś wyjaśnił problem nieco bardziej dogłębnie i opisał, co próbujesz zrobić, byłoby trochę łatwiej pomóc. (:

 -1
Author: A Person,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-05 04:41:03