Assembler podstawowe operacje - kilka pytań

Assembler podstawowe operacje - kilka pytań
0

Pytanie 1. ustawianie bitów - rozumiem ze robi się to przez ustawienie maski + operacja logiczna. Rozumiem że może być taka sytuacja, że wynik który chce otrzymać nie uda mi się zrobić jedną maską i operacją logiczną tylko będę musiał np. zrobić 2x maskę + operacja logiczna ?

Przykład z wikipedi: zerowanie dwóch najmłodszych bitów

operacja AND

Słowo: 10010111
Maska: 11111100
Wynik: 10010100

Pytanie 2. co do maski czy to ma jakieś znaczenie czy zamiast tej maski dam np. taką: 10011100. Wynik będzie ten sam.

Pytanie 3.

Mam takie 2 instrukcje czym one się różnią:

ORR R1, #(1<<28):OR:(1<<26)
MOV R2,#((1<<13) :OR: (1<<14)) // maska -> ustawienie jedynek na 13 i 14 pozycji ?

Pytanie 4. Po co się robi takie operacje, to STR na końcu ?

LDR R0, =RCC_AHB1ENR
LDR R1, [R0] //odczyt
ORR R1, #1<<6 //przesuniete o 6 miejsc zgodnie z kierunkiem strzalek //mod
STR R1, [R0] //zapis

Pytanie 5.

Instrukcja STR

Powiedzmy, że mam:

LDR R1,[R0]
STR R1,[R0]

Wiem, że STR zapisuje wartość rejestru w pamięci w przeciwieństwie do LDR który to ładuje wartość rejestru z pamięci.

Tylko, że ja nie rozumiem czym to się różni.

Pytanie 6.

Instrukcja TST

TST R1,#1

W jakim przypadku ustawiana jest flaga?

Jeżli do rejestru R1 wrzucę 0x01 to się nie ustawia. a już dla R1 = 0x02 tak. Czyli żeby ustawiła się flaga wynikiem muszą być same zera ?

TST to operacja AND czyli
dla R1 = 0x01 mam 01 & 01 = 01
dla R1 = 0x02 mam 10 & 01 = 00

Dla takiego kodu

Kopiuj

            1. CMP                R5,#255 ;
            2. ITE                  EQ ;
            3. MOVEQ           R1,#1<<13
            4. MOVNE           R1,#1<<29 ;reset jest na 29
            5. STR                R1,[R0]

  1. Porównuje wartość w rejestrze R5 z 255. Jeżeli jest taka sama ustawia się flaga Z = 1
  2. Jeżeli Z == 1 to wykona sie linijka 3, jeżeli nie to wykona się linijka 4.

Pytanie 7. Po co piszę MOVEQ / MOVNE ?? Równie dobrze mogę wywalić linijkę nr 2 ( ITE ) i też będzie chyba działać, lub zostawić ITE i zmienić MOVEQ -> MOV i MOVNE -> MOV

Z góry dzięki za pomoc

0

@Shalom @msm @Azarien pomożecie :) ?

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0
  1. To chyba tylko jak nie umiesz logiki :D Każdą zmianę można wykonać za pomocą jednej maski.
  2. Bez różnicy
  3. Nie wiem co to za asembler ale zgaduje że to STR to jakieś store register value i zapisuje wartość z R1 do miejsca w pamięci pod adresem zapisanym w R0. Po co? Ano żeby wartość zapisać w pamięci. Poza trywialnymi programami trudno wszystkie dane trzymać w rejestrach, bo rejestrów masz tylko kilka i mieszczą niewiele danych. A jeśli piszesz program który wczytuje Pana Tadeusza i zamienia wszystkie literki na duże? Gdzie chcesz tego Pana Tadeusza przechować? ;]
  4. Jak to nie rozumiesz czym się różni? o_O Jedno wczytuje wartość a drugie ją zapisuje. Wyobraź sobie że zapisujesz na dysku plik tekstowy o treści "ala ma kota", to jest odpowiednik STR. Rozumiesz chyba że otwarcie pliku i wypisanie jego zawartości na ekran (odpowiednik LDR) to jest zupełnie co innego?
  5. Tak trudno sprawdzić w dokumentacji http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/CIHCDEHH.html ? To po prostu ustawia jako flagę wynikową rejestr and operand.
  6. Wydaje mi się że masz racje, niepotrzebnie są tutaj dwa warunkowe mechanizmy na raz. Wystarczyłoby samo ITE + mov + mov, albo same moveq+movne

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
0
Shalom napisał(a):
  1. To chyba tylko jak nie umiesz logiki :D Każdą zmianę można wykonać za pomocą jednej maski.
  2. Bez różnicy
  3. Nie wiem co to za asembler ale zgaduje że to STR to jakieś store register value i zapisuje wartość z R1 do miejsca w pamięci pod adresem zapisanym w R0. Po co? Ano żeby wartość zapisać w pamięci. Poza trywialnymi programami trudno wszystkie dane trzymać w rejestrach, bo rejestrów masz tylko kilka i mieszczą niewiele danych. A jeśli piszesz program który wczytuje Pana Tadeusza i zamienia wszystkie literki na duże? Gdzie chcesz tego Pana Tadeusza przechować? ;]
  4. Jak to nie rozumiesz czym się różni? o_O Jedno wczytuje wartość a drugie ją zapisuje. Wyobraź sobie że zapisujesz na dysku plik tekstowy o treści "ala ma kota", to jest odpowiednik STR. Rozumiesz chyba że otwarcie pliku i wypisanie jego zawartości na ekran (odpowiednik LDR) to jest zupełnie co innego?
  5. Tak trudno sprawdzić w dokumentacji http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/CIHCDEHH.html ? To po prostu ustawia jako flagę wynikową rejestr and operand.
  6. Wydaje mi się że masz racje, niepotrzebnie są tutaj dwa warunkowe mechanizmy na raz. Wystarczyłoby samo ITE + mov + mov, albo same moveq+movne

Ad. 5 Dla mnie najdziwniejsze jest to że zapisuje to do R0 a przecież jak potem używam tego rejestru np dla LDR R0, [R6] to chyba nadpisuje to co zapisałem w R0, jaki to ma sens?

Mam jeszcze pytanie Czym różnią się od siebie operacje:

LDR R0, [R1]
i
MOV R0, [R1]

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

No bo tak jak pisałem rejestrów jest mało ale CPU potrafi operować tylko na nich. Nie da się np. dodać dwóch wartości z pamięci. Musisz je pobrać najpierw do rejestrów CPU. Stąd też non stop co innego musisz ładować do rejestrów. Ładujesz, wykonujesz obliczenia, zapisujesz wyniki i ładujesz coś innego. Nie traktuj rejestrów jako "zmiennych", bo to jest zupełnie inna koncepcja.

Jeśli chodzi o mov i ldr to jest to trochę bardziej złożona kwestia i wynika z tego że ARM ma instrukcje stałej długości (w opzeciwieństwie do jakiegoś x86 na przykład). To znaczy że każda instrukcja MUSI się zmieścić na z góry ograniczonej liczbie bajtów -> konkretnie na 4 bajtach. Nie trudno zauważyć że trudno byłoby w takim układzie zrobić mov do jakiegoś rejestru z wartością która miałaby 4 bajty, bo już samo mov i rejestr zabierają trochę z tych 4 bajtów na instrukcje, a gdzie jeszcze upakować tą wartość? Stąd też masz ldr które powoduje że kompilator wartość wrzuca do pamięci i w tej instrukcji ładuje z pamięci tą wartość do rejestru.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
JU
  • Rejestracja:około 22 lata
  • Ostatnio:około miesiąc
  • Postów:5042
0
Shalom napisał(a):
  1. Bez różnicy

Bez różnicy dla tego konkretnego przypadku. Jeśli chcesz wyzerować 2 najmłodsze bity na "przypadku ogólnym" to tak, jak mówi Wiki: 11111100.

0

A operacje odczyt modyfikacja zapis np. coś takiego

Kopiuj

                                1. LDR 	        R0,=GPIOG_MODER				;tryb pracy lini 13 i 14 portu G - wyjscie
				2. LDR		R1,[R0]
				3. ORR		R1,R1,#((1<<(2*13)) :OR: (1<<(2*14)))
				4. STR		R1,[R0]

rozumiem że to podstawowe operacje. Proszę o zweryfkowanie czy dobrze to rozumiem.

  1. Ładuje zawartość rejestru GPIOG_MODER do rejestru R0, rejestr GPIOG_MODER pozwala ustawić poszczególne bity w rejestrze jako wejścia albo wyjścia.

  2. W linijce 3 ustawiam te bity w rejestrze, czyli ustawiam bit 26 i bit 28 na 1 chyba. Tylko to szczerze mówiąc nie rozumiem jak działa ta cała linijka. Nie rozumiem tego zapisu.

No i potem mam to STR i do rejestru R1 czyli do rejestru gdzie mam poustawiane odpowiedno te bity w rejestrze zapisuje rejesre R0 w którym miałem niepoustawiane te bity. O co tu chodzi.. czy przez to nie nadpisuje tego co zrobiłem chwilę wcześniej ?

@Shalom bardzo Cie proszę o wyjaśnienie tego kodu.

Na zajeciach programowalismy tez ARM w C i rozumiem ze powyzszy zapis jest równoznaczny temu w C :

Kopiuj
GPIOG->MODER |= (1<<(2*13)) | (1<<(2*14));  // linie G13 i G14 jako wyjscia
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

o_O mam wrażenie że niestety ale programowanie to nie jest działka dla ciebie, bo brakuje ci czytania ze zrozumieniem i jakiegokolwiek rozumienia logiki...

  1. 2*13 = 26, a << to przesuniecie bitowe w lewo, czyli dodawanie zer z prawej strony liczby binarnej. Tzn 1<<3 daje nam 1000, czyli liczbę z zapalonym 4 bitem.
  2. STR to jest store register to memory o czym juz wyżej pisałem. To NIE JEST operacja na rejestrach! W twoim przypadku masz STR R1,[R0] czyli zapisanie wartości rejestru R1 do PAMIĘCI pod adresem wskazanym przez R0.

Co więcej ja na ARM znam się bardzo słabo, ale potrafie otworzyć http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/BABDJCHA.html i sie upewnić...


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)