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
endA 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.