2010-04-12 6 views
14

Właśnie zaczynam studiować język asemblera ARM, i nie jestem pewien jak używać MOV do przeniesienia bezpośredniej liczby do rejestru.Jak używać instrukcji MOV w ARM z bezpośrednim numerem jako drugim operandem

Z podręcznika referencyjnego ARM i mojego podręcznika wynika, że ​​zakres natychmiastowej liczby po instrukcji MOV wynosi 0-255. Ale kiedy testuję na własnym komputerze w ADS 1.2 IDE, instrukcja

MOV  R2, #0xFFFFFFFF 

wykonuje się dobrze. Czy liczba 0xFFFFFFFF poza zakresem nie jest zgodna ze specyfikacją?

Mam nadzieję, że ktoś może mi pomóc.

Pozdrawiam.

Odpowiedz

12

Pamiętaj, że ARM może wykonać pewien zestaw manipulacji na bezpośredniej wartości jako część przesuwnika beczki, który jest wbudowany w kody operacyjne ARM.

Ten mały artykuł jest jednym z najczystszych wyjaśnień niektóre sztuczki, że asembler ARM można użyć do dopasować dużego natychmiastowy numer w małej dostępnej przestrzeni instrukcji ARM:

W artykule omówiono lewę, która jest prawdopodobnie używana w konkretnym przykładzie generowania kodu operacyjnego MVN w celu załadowania uzupełnienia bitowego o wartość bezpośrednią.

Ten rodzaj manipulacji nie może być wykonany z wszystkimi bezpośrednimi wartościami, ale asemblery ARM są podobno dość inteligentne (i kompilatory C z pewnością są). Jeśli nie można wykonać żadnych sztuczek z przesunięciem/dopełnieniem, wartość będzie zwykle ładowana z lokalizacji względem komputera lub może "budować" wartość z kilku instrukcji.

+0

@Michael Dzięki za porady. Właśnie tego chcę wiedzieć! :-) –

+0

Czy ktoś wie ** dlaczego ** asembler buduje niektóre wartości, ale załaduje inne bezpośrednio? Rozglądanie się po kodzie Newtona ROM (StrongArm 110) ma wiele "ładunków jednoosobowych" (jak "MOV r1, 0x0c1b518"), ale cały mój kod wychodzi z "ładunkiem nagromadzonym" - jak poniższy kod: –

+0

.. (Ups, wczesny błąd księgowania) .. jak "MOV r1, 0x0C000000/ADD r1, r1,0x100000". Zakładam, że może to mieć coś wspólnego z tym, jak procesor koduje wartości 32-bitowe. Czy procesor mikrokodu jest wydajniejszy w budowaniu liczb przy użyciu pojedynczego pliku MOV, a następnie ADD? –

-1

Jedna z możliwości polega na tym, że asembler ARM wyrzuca znaczące bity liczby i używa tylko najniższego FF.

Instrukcja MOV jest zszywaczem wielu zestawów instrukcji procesora i zazwyczaj asembler rozpoznaje rozmiar rejestru docelowego i dostarczaną wartość bezpośrednią.

Na przykład następujące instrukcje MOV z zestawu x86 są

MOV BL, 80h, ; 8bit 
MOV BX, ACACh ;16bit 
MOV EBX, 12123434h ; 32bit 
1

Być może widząc artefakty z logowania rozszerzenie pierwotnej wartości. Jeśli narzędzia używane do przeglądania demontażu obsługują 0..255 jako bajt z podpisem, to po załadowaniu go do większego typu int (lub rejestru) wypełni on wszystkie górne bity bitem znaku oryginału wartość. Lub mówiąc inaczej, jeśli 0xFF jest bajtem ze znakiem, jego wartość dziesiętna wynosi -1. Umieść to w rejestrze 32-bitowym, a hex będzie wyglądał jak 0xFFFFFFFF, a jego wartość dziesiętna nadal będzie równa -1.

Spróbuj użyć wartości bez zestawu wysokich bitów, na przykład 0x7F. Ponieważ bit znaku nie jest ustawiony, domyślam się, że wypełni on górne bity zerą, gdy zostanie załadowany do większego rejestru lub pola typu int.

Jest również możliwe, że kompilator/asembler obcina dowolną wartość, którą podasz. Uznałbym to za błąd kodu źródłowego, ale asemblery są zabawnymi zwierzętami. Jeśli nadasz mu 0x7FF, czy kompiluje się do 0x7FF (nie obcięty i większy niż 0..255) lub do 0xFFFFFFFF (obcięty do 0..255, bajt z podpisem)?

11

Pojedyncza instrukcja ARM może kodować bezpośrednią stałą, która może być reprezentowana jako 8-bitowa wartość bezpośrednia, przesunięta o dowolną wartość równą , nawet.

Jednak istnieje również instrukcja MVN, która jest podobna do MOV, ale odwraca wszystkie bity. Tak więc, podczas gdy MOV R2, #0xFFFFFFFF nie może być zakodowany jako instrukcja MOV, może być zakodowany jako MVN R2, #0. Asembler może wykonać tę konwersję dla ciebie.

1

Ciężko jest określić, czy podane stałe mieszczą się w dopuszczalnym zakresie.

jak Matthew już wspomniano, monter pożycza ci rękę, zastępując podane instrukcje z podobnym, negując te, jak MOV/mvn, cmp/cmn, TST/tne itp

2

instrukcja MOV może zaakceptować lub wartość imm16 wartość Operator2 (ze względu na długość instrukcji przeciwieństwie do wyrównania pamięci), który musi być zgodny którykolwiek z następujących reguł (skopiowane z CortexM Zestaw instrukcji obsługi, X i Y jest dowolny hex-value):

  • Wszelkie stałe, które mogą być generowane przez przesuwanie 8-bitowej wartości pozostawionej przez dowolną liczbę bitów w 32-bitowym słowie .
  • Każda stała w postaci 0x00XY00XY.
  • Każda stała w postaci 0xXY00XY00.
  • Dowolna stała w postaci 0xXYXYXYXY.

To jest powód, dla którego przyjęto 0xFFFFFFFF (spełnia 4. regułę).

Jeśli chcesz złożyć własną stałą 32-bitową, możesz użyć instrukcji MOVT, która zapisuje do górnej połowy rejestru.

+0

Dlaczego więc nie pozwoliłoby to na 0x45454545? Właściwie nawet 0x00450045. – JSmyth

Powiązane problemy