fasm. Program wyświetlający liczby binarnie.

0

Dopiero zaczynam się uczyć Asemblera. Oto kod programu do którego mam pytania:

1format ELF64 executable
2entry _start
3
4segment readable executable
5
6_start:
7	
8	mov esi, 0fh
9	
10	mov eax, "0"
11	mov ebx, nasze_flagi
12	xor edi, edi
13	
14	mov cx,32
15	
16petla:
17	and al, "0"
18	shl esi, 1
19	adc al, 0
20	mov [ebx+edi], al
21	inc edi
22	loop petla
23	
24	mov eax,4
25	mov ebx, 1
26	mov ecx, nasze_flagi
27	mov edx, 32
28	int 80h
29	
30	mov eax,1
31	xor edi,edi
32	int 80h
33
34segment readable writeable
35	
36nasze_flagi:	times	64	db	"0"

Numerów linii nie ma w programie. Mam następujące pytania:

  1. Po co 10 linia? Program bez niej nie działa, ale przecież rejestr EAX nie jest używany aż do 24 linii.
  2. Co robi linia 17?
  3. Co robi linia 19?
  4. Co to jest [rejestr]? Co robi linia 20?
  5. Linia 22. Czemu pętla się kończy? Gdzie zmienia się rejestr CX, który odlicza powtórzenia?
  6. Gdzie zmienia się zmienna nasze_flagi? Linie 24-28 tylko ją wyświetlają.
  7. Program się kompiluje i uruchamia ale Makefile zgłasza "Błąd 1". Dlaczego?
0

przecież rejestr EAX nie jest używany aż do 24 linii

Używany jest za to al, który stanowi część eax.

Co to jest [rejestr]? Co robi linia 20?

W tym wypadku oznacza to zapisanie bajtu al pod komórkę w pamięci znajdującą się pod adresem ebx + edi.

Czemu pętla się kończy?

loop sprawdza czy ecx > 0 - jeśli tak, od rejestru ecx odejmowane jest 1 i sterowanie przeskakuje do etykiety wskazanej w argumencie loop; jeśli ecx == 0, loop nic nie robi (sterowanie "wyskakuje" poza pętlę).

Na przykład:

mov ecx, 5
repeat:
  nop
  loop ecx

... spowoduje uruchomienie instrukcji nop pięć razy.

Gdzie zmienia się zmienna nasze_flagi?

Instrukcja mov ebx, nasze_flagi zapisuje do rejestru ebx adres nasze_flagi, a następnie mov [ebx+edi], al tę część pamięci modyfikuje.

1
  1. eax składa się z ax a ten z al i ah
  2. Efektywnie to samo co mov al, "0" :) Bo wiemy że al albo jest "0" albo "1", więc taki and w praktyce wpisze do rejestru "0" (bo różnią sie co najwyżej ostatnim bitem a "0" na ten bit zgaszony). Taki hax bo pewnie instrukcja and jest krótsza/szybsza.
  3. Mamy w al "0" a teraz dodajemy 0 albo 1 w zależności od flagi carry którą ustawił nam wcześniejszy shift left. Masz np. liczbę 1010 w esi, robisz shl esi,1 więc zostaje ci w esi 010, a ta jedynka co poszła w lewo przekroczyła zakres liczby i poleciała do flagi carry. I teraz adc efektywnie doda ją do "0" robiąc z niego "1". Czyli jeśli najwyższy bit aktualnie w esi jest 0 to al nadal będzie "0" a jak był 1 to zmieni al na "1"
  4. mov [ebx+edi], al to wpisanie wartości al (czyli "0" albo "1") do pamięci pod adresem ebx+edi. W tym przypadku edi to indeks a ebx to adres tablicy do której piszesz. Zapis [rejestr] oznacza odwołanie się do pamięci pod adresem w rejestrze, coś jak * w C. To byłoby coś w stylu *(ebx+edi) = al albo prościej ebx[edi] = al jakby to zapisać składnią C, a że wiemy że mov ebx, nasze_flagi to faktycznie robimy nasze_flagi[edi] = al
  5. loop label robi mniej więcej dec cx; test cx, jnz label
  6. Zauważ że masz mov ebx, nasze_flagi a więc odwołania [ebx+X] odnoszą się do tego miejsca w pamięci
  7. Czym to kompilujesz? Jaki błąd?
0

@Shalom: do kompilowania używam fasm 1.73.22. Zmieniłem xor edi,edi na xor ebx,ebx i błąd zniknął. Dziękuję za odpowiedzi.

1

Ty sobie robisz jaja z tą zamianą? xD Przecież to teraz nie będzie działać w ogóle. xor edi, edi miało wyzerować ci edi żeby zacząć od indeksu 0 w tablicy. Możesz tam dać równie dobrze mov edi, 0 albo liczyć na to ze akurat edi ma 0 :D
A wyzerowanie ebx trochę nie ma sensu, bo przecież chcesz mov ebx, nasze_flagi!

Chyba ze mówisz o tym xor edi,edi na końcu kodu, ale to odpowiada na error code na wyjściu programu :D Jak wywalisz xor edi,edi i nie dasz jakiegoś mov edi, 0 to kod wyjścia z programu będzie inny niż 0, czyli sygnalizuje błąd.

Rozumiesz ze nie programuje się metodą permutation driven development? Każda z tych instrukcji coś oznacza i nie można ich sobie losowo zamieniać.

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