kategoria: Asembler
[#1] Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?
Czołem wszystkim!

Zaczynam uczyć się asemblera Amigowego i z ciekawości postanowiłem przyjrzeć się, co vbcc zrobi z najprostszym możliwym programem w C po przetłumaczeniu go na asembler:

// main.c
extern long blah(char *);

int main() {
  long a = blah("2a");
}


Wszystko niby wygląda OK, ale jak przyglądam się temu rezultatowi to za cholerę nie jestem w stanie dociec, czym jest "reg" w wygenerowanym kodzie źródłowym i czemu on służy? Czy to instrukcja procesora, dyrektywa asemblera, jakieś predefiniowane makro, czy jeszcze coś innego?

// main.s
        idnt    "main.c"
        opt o+,ol+,op+,oc+,ot+,oj+,ob+,om+
        section "CODE",code
        public  _main
        cnop    0,4
_main
        subq.w  #4,a7
        movem.l l4,-(a7)
        pea     l3
        jsr     _blah
        move.l  d0,(4+l6,a7)
        moveq   #0,d0
        addq.w  #4,a7
l1
l4      reg
l6      equ     0
        addq.w  #4,a7
        rts
        cnop    0,4
l3
        dc.b    50
        dc.b    97
        dc.b    0
        public  _blah


Czy ktoś coś wie i podzieliłby się łaskawie swoją wiedzą? Googlałem długo i na żadne wskazówki nie natrafiłem.

Z góry wielkie dzięki!
1
[#2] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #1

ChatGPT nie miał problemu z wyjaśnieniem tego szczegółowo i po polsku. Gdy zapytałem Google to też w pierwszej odpowiedzi (tej generowanej przez AI) dostałem podobną odpowiedź. Czy to jest zgodne z prawdą to nie wiem, bo zupełnie się na tym nie znam. Ale zaraz się przekonamy gdy pojawią się odpowiedzi kompetentnych organizmów węglowych opartych na chemii organicznej.

Ostatnia aktualizacja: 09.02.2026 21:38:43 przez MDW
1
[#3] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #1

Z ChatGTP5.2:
In that listing, `reg` is NOT a 68000 CPU instruction. It is an
assembler directive used to define a MOVEM register mask constant.

What it is doing here:

You have:

```
movem.l l4,-(a7)
...
l4      reg
```

So the label `l4` is being defined as a register-list value (a bitmask)
that MOVEM can use.

Many 68k assemblers (and C compilers that emit assembly) support a
`REG` directive to build the 16-bit MOVEM mask:

```
bits 0–7   -> D0–D7
bits 8–15  -> A0–A7
```

Example (what it could look like):

```
l4  reg  d2-d3/a2-a3
; l4 becomes the corresponding MOVEM mask
```

Why is it empty (`l4 reg` with no list)?

In your snippet it is blank, so it typically means:

```
no registers need saving, so the mask is 0
```

Compilers often still emit the movem + reg pattern as a template, even
when the set ends up empty.

So effectively, in this function, it is saying:

```
"Here is the register-save mask for this function (and it happens
 to be empty)."
```

If you later saw an epilogue like:

```
movem.l (a7)+,l4
```

it would use the same mask to restore the saved registers (though your
snippet does not show that restore).
1
[#4] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@ppill, post #3

Interesujące podsumowanie... Właśnie ten brak "movem.l (a7)+,l4" mnie nieco skonfudował, bo bez tego nie zgadzają mi się pointery "a7" przed rozpoczęciem i po zakończeniu działania programu. Sprawdzę to sobie pod debuggerem, to może się wyjaśni ostatecznie. Dziękuję za odpowiedź!
[#5] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #4

Nie wiem czy o to chodziło ale proszę:

Good catch to question it - but in this specific snippet, no, it would
not cause a pointer or stack misalignment because `l4 reg` is
effectively an empty MOVEM mask.

What happens to A7 (the stack pointer) in your code:

Let us track the stack pointer changes step by step.

1. Prologue reserve:
   subq.w #4,a7
   A7 = A7 - 4

2. Save registers:
   movem.l l4,-(a7)
   This would push the registers listed in `l4`.

   But since `l4 reg` has no register list, the mask is 0.
   That means it pushes nothing.

   Net effect: A7 unchanged.

3. Push argument:
   pea l3
   Pushes 4 bytes.

   A7 = A7 - 4

4. Call:
   jsr _blah
   The CPU pushes the return address (4 bytes).

   During the call:
   A7 = A7 - 4

   When `_blah` executes RTS, the return address is popped,
   so A7 returns to the value it had just before JSR.

   After return:
   A7 = original - 4 - 4

5. Clean up argument:
   addq.w #4,a7
   Pops the argument pushed by PEA.

   A7 = original - 4

6. Epilogue:
   addq.w #4,a7
   Undoes the initial stack reservation.

   A7 = original value

So the stack is balanced.

When would it be a problem?

It would be a problem if `l4` were non-empty (for example saving
d2/a2) and you did not restore it with something like:

movem.l (a7)+,l4

Because `movem.l l4,-(a7)` would decrement A7 by 4 times the number of
registers saved. If you never increment A7 by the same amount, you
would return with A7 incorrect and RTS would jump to the wrong address.

Even with an empty mask, some assemblers may still encode MOVEM, but it
effectively moves zero registers and has no effect on A7.

Bottom line: in your snippet, missing the restore does not misalign
anything as long as `l4` really resolves to mask 0. If `l4` ever
includes registers, then yes, it would break the stack unless restored
or A7 adjusted by the same amount.
[#6] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #4

REG interpretuje asembler jako listę rejestrów, opatrzoną etykietą.

Ta lista może być podstawiona pod instrukcję MOVEM, która pobiera listę rejestrów.

Przykładowo asembler DAS wchodzący w skład DICE, też tworzy takie etykiety i używa REG.

Najczęściej MOVEM służy do zapamiętania rejestrów na stosie i odtworzenia ich, albo do przekazania parametrów przez stos.

Fragment:

subq.w  #4,a7

Tworzy miejsce na stosie. Fragment:

addq.w  #4,a7

Odwraca powyższą operację, przywracając poprzedni wskaźnik na stos. Musi być wywołany do "naprawienia" stosu np. po wywołaniu funkcji, która pobiera parametry przez stos.

Częściej do ramki stosu, która jest używana do zmiennych lokalnych używa się polecenia LINK:

link.w a5,#-16

ponieważ przy okazji przydziela ono rejestr, który wskazuje na ramkę stosu i dodatkowo jest zapamiętywany. Po użyciu ramki wywołujemy polecenie UNLK, by przywrócić wskaźnik na stos oraz ten rejestr, np.:

unlk a5

Fragment dokumentacji do DAS:

DAS handles the following directives:

	DC		declare data
	DS		declare space / align

	SECTION 	declare a section.  Sections may be repeated to flip
			back and forth between them.  A third argument
			may contain a value to be ORd with the hunk
			type field, usually used to specify special
			hunk flags (i.e. hunk to chip memory, etc...)

	XREF		import a label
	XDEF		export a label
	EQU		declare a constant (must be a numerical constant)
	REG		declare zero or more registers in register list

        ...

	* MOVEM's using 'reg' labels are optimized to either a MOVE or by
	  removing the MOVEM entirely (reg labels that specify no registers).


Ostatnia aktualizacja: 09.02.2026 22:04:01 przez Hexmage960
[#7] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@ppill, post #5

Cool! To było pomocne. Ostateczne wyjaśnienie jest takie, że vasm z takiej linijki nie "wyprodukuje" żadnego kodu do wynikowej binarki:

movem.l  l4,-(a7)
l4  reg

Sprawdziłem to sobie na dwa sposoby - 1. disasemblacja skompilowanego programu (ani śladu po instrukcji), 2. powtórzenie tej samej instrukcji wiele razy nie wpływa w żaden sposób na wielkość ani zawartość pliku wynikowego.
[#8] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #7

Vasm lubi sobie pooptymalizować, czasem do przesady, chociaż tu akurat optymalizacja jest oczywista.
[#9] Re: Co oznacza instrukcja/dyrektywa/makro "reg" w vasm?

@djgruby, post #7

Nie musisz tego ustalać empirycznie.

W dokumentacji do vasm jest to opisane:

<symbol> reg <reglist>

Defines a new symbol named <symbol> and assign the register list <reglist> to
it. Registers in a list must be separated by a slash (/) and ranges or registers
can be defined by using a hyphen (-). Examples for valid register lists are:
d0-d7/a0-a6, d3-6/a0/a1/a4-5.

Ja akurat używałem często DICE, stąd pamiętam to REG.

Dla kompilatora jest to wygodne ustawianie w ten sposób takich grup rejestrów w postaci odwołań do etykiety.

Nie wiem natomiast do czego służy to odwołanie w tej funkcji, którą podałeś.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem