( bucko | 2016. 07. 06., sze – 09:39 )

Ez az első kijelentés pozitív!

Ezek szerint láttál már "valódi assembler fordítót is". A MASM nem 8048-ra fordít, hanem pc processzorra. A másik meg az ASM48 lehetett, de az Intel termék.
Bár 1983-tól a VIDEOTON Fejlesztési Intézetben dolgoztam, de komolyan mondom: Azt a monitort nem én adtam el! ;)

Nincs szegmens regiszter, ...
Hát dehogy nincs! Azért mert banknak hívják, a memória bájtot meg (memory)file register-nek attól még az.

Ez egy 8086-os kód
mov ax,@Data
mov ds,ax
assume ds:Data

Ugyanex PIC-re
movlw @Bank0
movwf BSR, a
assume BSR:Bank0

Az assume azt jeleni amit jelent: Tételezd fel, hogy a következő sortól kezdődő kódban a ds (data segment register)/bsr (bank select register) által végzett címzés a Data/Bank0 címkével jelzett memóriaterületre (szegmensre/bankra) vonatkozik! Minden olyan címzés, ami az előbbieknek megfelel azt tekintsd jónak, ami ettől eltér azt tekintsd hibának és jelezd! Nem írom le az összes x86 címzési módot ami megfelelő, de PIC esetén a ...,b vagy a default, ha elhagyod a b-t.

Az eltérés a következő:
BANKSEL
This directive generates bank selecting code...
Tehát ez a direktíva - ami inkább egy okos beépített makró - kódot generál (esetleg mégsem) a különböző felépitésű processzorok számára.
Hatása - ha figyeled - a kód blokk végéig terjed. Vagy a következő call-ig, de ez egy, másik téma.

ASSUME
...but you must also tell the assembler where and when that segment is a data ...segment. The assume directive provides this information to the assembler.
Tehát az assume nem generál kódot, csak a fordítót informálja, hogy mit higgyen a regiszter tartalmáról. A regiszter betöltéséhez meg kell írnod a kódot, mint a fenti példában. De a regiszter betöltéséhez semmi köze se oda, se vissza.

Példa:

#include <P18F24K50.INC>
        list n=0, st=off
        cblock  400
        Bank4:0
        Bank4_data
        endc

        cblock  500
        Bank5:0
        Bank5_data
        endc

        org        0
        movlb      4
        call       Bank4DataManipulation
;       assume     BSR:NOTHING          ;a call miatt automatikusan
        call       Bank5DataManipulation
stop
        bra        stop

Bank4DataManipulation
;       assume     BSR:Bank5            ;helyesen: high Bank4, de ezt a fordítónak kellene megoldani
;ezek az üzenet nem mond semmit, a nincs ASSUME
        movf       Bank4_data,w,b       ;ASSUME -> helyes
        movf       Bank5_data,w,b       ;ASSUME -> hibás
        movf       Bank4_data,w,a       ;high ADDRESS != BSR -> hibás
        return

Bank5DataManipulation
        movlb       5
;       assume      BSR:Bank5           ;helyesen: high Bank5, de ezt a fordítónak kellene megoldani
        movf        Bank5_data,w,b      ;ASSUME -> helyes
        movf        Bank4_data,w,b      ;ASSUME -> hibás
        movf        Bank4_data,w,a      ;high ADDRESS != BSR -> hibás
        return

        end

A BANKSEL felülírhatja az assume által megadott értéket.
Mondhatnád, hogy legyen a banksel az assume, mert ha nem kell, akkor nem generál kódot. Ennek ellenére eléggé ovashatatlanná teheti a forrást. Meg nem feltétlenül kell kényelmi szempontokból állandóan banksel-ezni.

Mindenesetre ez a módszer sokkal kifinomultabb, mint a fordítottja, amikor kiírod mit hisz a fordító. Van az az ugrótábla, amiről még én sem tudom mit is csinál, pedig én írtam. ;) Egy fordítótól - ami nem szimulátor - meg nem várható el a kód ilyen fokú elemzése.

Megint jó kérdés a call. Hasonló (csak egy kicsit és pongyolán) C-ben a

#pragma isolated_call function

Ez azt jelenti, hogy a function nem változtatja meg a változók értékét, tehát nem kell automatikusan menteni a függvényhívás előtt.
Tehát eldöntendő vagy egy direktívával szabályozni kell, hogy globális vagy kód blokk hatókörű az assume.