8086 TASM: Hallo, guten tag. Wie bekommt man bitte die beiden DWord in das lds si,... rein ? Oder das DWord SegAddr in DS und das andere DWord ofs in si ? Ich kann nur das DWord zur Übergabe hier übergeben. Danke. ----------------------- public pcopykl pcopykl Proc SegAddr:DWord , ofs:DWord lds si,.... ... ... ret pcopykl Endp ----------------------- Oder wie bekomme Dword SegAddr hier in ax bzw ds und DWord ofs in ax bzw in si ? ------------------------ mov ax,SegAddr mov ds,ax mov ax,ofs mov si,ax -----------------------
:
Bearbeitet durch User
DWord (Double Word) = 32bit passt nicht in ein Word = 16bit Willst du deine Frage also nochmal anders stellen Ein segment oder offset kann (bei dir) nur Word breit sein
cppbert schrieb: > DWord (Double Word) = 32bit passt nicht in ein Word = 16bit > Willst du deine Frage also nochmal anders stellen > > Ein segment oder offset kann (bei dir) nur Word breit sein Deine Parameter sind einfach zu gross, wie kommst du jetzt plötzlich auf DWord?
Ich kann nur DWord übergeben. Ich brauche für ds und si jeweils die unteren 2 Byte aus den beiden DWord. Wie kann ich bitte ein DWord aufteilen für DS und das andere DWord für si ? Danke.
:
Bearbeitet durch User
Peter B. schrieb: > Wie bekommt man bitte die beiden DWord in das lds si,... rein ? Solange du
1 | Model Medium, Basic |
2 | .Code |
und uses nicht verstanden hast gar nicht. Als Tip schau einfach mal im lst File was diese vereinfachten Anweisungen so bewirken. Ein weiterer Hinweis: Parameter werden bp relativ addressiert.
Warum BP, dieses funtioniert. Ist aus einer DEmo. --------------------------- public PokeWord PokeWord Proc Uses ES, SegAddr:DWord, Value:Word Les BX,SegAddr Mov AX,Value Mov ES:[BX],AX Ret PokeWord Endp ----------------------------
Ich gebe auf... Schau jetzt einfach mal ins lst file, oder fang damit an Blumen zu züchten.
Peter B. schrieb: > PokeWord Proc Uses ES, SegAddr:DWord, Value:Word Warum geht es bei nur mit DWord und dem Beispiel gehts auch mir Word - woher kommt die Einschränkung? Zerlegen von Words w / 256 w mod 256 Bei DWords eben mit 65536 in Words zerlegen Einfach mit dem Taschenrechner ausprobieren
und noch was... Glaubst du wirklich, dass mov ax,Value ein gültiger Assembler Befehl ist? Wenn ja gibt das einfach mal in debug ein.
AlleDemos die ich für den MASM und TASM finde laufen nach dem Schema ab und erfüllen den Zweck:
1 | .model medium,basic |
2 | .code |
3 | .286 |
4 | |
5 | public SumArray |
6 | |
7 | SumArray Proc Uses SI, Array:DWord, NumEls:Word, Sum:Word |
8 | |
9 | Push DS ;save DS so we can restore it later |
10 | Push SI ;PDS far strings require saving SI too |
11 | |
12 | Xor AX,AX ;clear AX and DX which will accumulate |
13 | Mov DX,AX ; the total |
14 | |
15 | Mov BX,NumEls ;get the address for NumElements% |
16 | Mov CX,[BX] ;read NumElements% before changing DS |
17 | Lds SI,Array ;load the address of the first element |
18 | Jcxz Exit ;exit if NumElements = 0 |
19 | |
20 | Do: |
21 | Add AX,[SI] ;add the value of the low word |
22 | Adc DX,[SI+2] ;and then add the high word |
23 | Add SI,4 ;point to the next array element |
24 | |
25 | Or SI,SI ;are we beyond a 32k boundary? |
26 | Jns More ;no, continue |
27 | |
28 | Sub SI,8000h ;yes, subtract 32k from the address |
29 | Mov BX,DS ;copy DS into BX |
30 | Add BX,800h ;adjust the segment to compensate |
31 | Mov DS,BX ;copy BX back into DS |
32 | |
33 | More: |
34 | Loop Do ;loop until done |
35 | |
36 | Exit: |
37 | Pop SI ;restore SI for BASIC |
38 | Pop DS ;restore DS and gain access to Sum& |
39 | Mov BX,Sum ;get the DGROUP address for Sum& |
40 | Mov [BX],AX ;assign the low word |
41 | Mov [BX+2],DX ;and then the high word |
42 | |
43 | Ret ;return to BASIC |
44 | |
45 | SumArray Endp |
46 | End |
Ich bin darin ein Greenhorn und versuche dann die Demos zu verstehen wenn sie funktionieren. Danke.
1 | Peter B. schrieb im Beitrag #6241757: |
2 | > --------------------------- |
3 | > public PokeWord |
4 | > PokeWord Proc Uses ES, SegAddr:DWord, Value:Word |
5 | > Les BX,SegAddr |
6 | > Mov AX,Value |
7 | > Mov ES:[BX],AX |
8 | > Ret |
9 | > PokeWord Endp |
10 | > ---------------------------- |
Derjenige der diesen code geschrieben hat hatte es wohl auch nicht ganz verstanden. Der Bezeichner SegAddr ist Mist, da es sich hier um eine vollständige Adresse Handelt, Die auch richtig in das Registerpaar ES:BX geladen wird. Dort sollte besser TargetAddress stehen. Das Uses ES bewirkt das am anfang ein Push ES und am ende ein Pop ES vom Assembler in den Code eingefügt wird.
Ich sag's nochmal.... Solange du nicht verstehst was das ASM Schlüsselwort Basic bewirkt brauchst du gar nicht weiterzumachen. Neben einigen subtilen Bedeutungen sorgt es beispielsweise dafür das ret nach retf übersetzt wird. Du kannst dich sicher noch an far bei deinen c Versuchen erinnern. Nächster Punkt ist proc. Das sorgt dafür dass du sowas schreiben kannst: mov AX,Value das wir dann übersetzt zu mov AX, [BP +??]. +?? Ist dabei deine Parameter Position. -?? wäre übrigens eine lokale Variable. In beiden Fällen sind die tatsächlichen Zahlen abhängig ob du das Basic Keyword benutzt. Ich hatte dir ja schon geschrieben dass es unabdingbar ist die Calling Conventions zu verstehen wenn gemischte Programmierung im Spiel ist. Hier ist nicht der Platz um dir entsprechende Ausschnitte aus dem ASM Handbuch vorzulesen.
Peter B. schrieb: > Ich bin darin ein Greenhorn und versuche dann die Demos zu verstehen > wenn sie funktionieren. Aber es funktioniert doch ein deinen Beispiel, oder? Warum fragst du dann wie man das zum laufen bekommt? Oder stürzt der Code ab?
Wo gibt es denn bitte aufklärende kleine Lektüre für den TASM (DOS) als PDF in deutsch? Danke.
Kannst du bitte die Fragen beantworten? du hast das gepostet >Hallo, guten tag. >Wie bekommt man bitte die beiden DWord in das lds si,... rein ? >Oder das DWord SegAddr in DS und das andere DWord ofs in si ? > >Ich kann nur das DWord zur Übergabe hier übergeben. > >Danke. >----------------------- >public pcopykl >pcopykl Proc SegAddr:DWord , ofs:DWord > > lds si,.... und dann irgendwann das >SumArray Proc Uses SI, Array:DWord, NumEls:Word, Sum:Word > > Push DS ;save DS so we can restore it later > Push SI ;PDS far strings require saving SI too > > Xor AX,AX ;clear AX and DX which will accumulate > Mov DX,AX ; the total > > Mov BX,NumEls ;get the address for NumElements% > Mov CX,[BX] ;read NumElements% before changing DS > Lds SI,Array ;load the address of the first element die letzte Zeile hier in DEINEM SumArray Beispiel macht doch genau das was du gefragt hast - ist die Frage jetzt verändert oder was ist dein Problem? Egal wie wenig Wissen du hast - anständig Fragen stellen hat damit wirklich nichts zu tun
cppbert schrieb: > die letzte Zeile hier in DEINEM SumArray Beispiel macht doch genau das > was du gefragt hast - ist die Frage jetzt verändert oder was ist dein > Problem? oder sind die Beispiele die du zeigt nur teilweise funktionsfähig - was du definitiv nicht schreibst und dann wandern deine Fragen irgendwie weg von der Initalfrage...
Nein, mit Sumarray meine ich , das ich solche Demo-Programme benutze um zu sehen wie es funktioniert. Aber irgendwie stimmen die auch nicht , weil manche Demos hier als unrichtig eingestuft werden. Wo soll man denn anfangen zu lernen?
Peter B. schrieb: > Nein, mit Sumarray meine ich , das ich solche Demo-Programme > benutze um > zu sehen wie es funktioniert. > Aber irgendwie stimmen die auch nicht , weil manche Demos hier als > unrichtig eingestuft werden. > > Wo soll man denn anfangen zu lernen? Du vergisst immer wieder das wir nicht in deinem Kopf sitzen - keiner weiß genau was du davon jetzt getestet, verworfen, jetzt anders machst , Gründe für das Problem ware, neue Lösung - das alles lässt du einfach im Dunkel UND BEANTWORTEST SEHR SELTEN FRAGEN z.B. 1. Ich hab immer noch keine Ahnung warum du NUR DWord übergeben kannst??? 2. Warum die LDS,SI Beispiele aus deinen EIGENEN Posts deine EIGENEN Frage nach wie LSD,SI funktionier nicht beantworten??? und du ignorierst die Fragen einfach und fragst dann einfach andere Dinge...
Was ist das zb für eine Meldung die ich nicht verstehe? ----------------------------------- .model medium,basic .code .286 public pcopykl pcopykl proc SegAddr:DWord, ofs:DWord mov ax,[WORD SegAddr] mov bx,[WORD ofs] ret pcopykl Endp End -----------------------------------
Für den Bildschirm kopieren in VGA-MX im PDS-Basic wird Long übergeben, weil es größer ist wie Integer, es gibt kein unsigned Int. Die For-Schleife habe ich für ASM umgesetzt. DEF SEG = &HA000 + dstPage * 1000 FOR i% = 0 TO 15999 POKE i%, PEEK(ofs + i%) NEXT i% DEF SEG ofs und segm ist LONG in: ofs = CLNG(srcPage - dstPage) * 16000 segm= &HA000 + dstPage * 1000 call pcopykl(segm,ofs) Die original Sub : -------------------------------------------------- SUB yPAGECOPY (dstPage AS INTEGER, srcPage AS INTEGER) DIM ofs AS LONG OUT scINDEX, scMapMask ' select plane masking function OUT scDATA, &HF ' select all four planes OUT gcINDEX, gcBitMask ' select CPU bit masking function OUT gcDATA, &H0 ' unmask all bits IF (dstPage < srcPage) THEN ofs = CLNG(srcPage - dstPage) * 16000 DEF SEG = &HA000 + dstPage * 1000 FOR i% = 0 TO 15999 POKE i%, PEEK(ofs + i%) NEXT i% ELSE ofs = CLNG(dstPage - srcPage) * 16000 DEF SEG = &HA000 + srcPage * 1000 FOR i% = 0 TO 15999 POKE (ofs + i%), PEEK(i%) NEXT i% END IF OUT gcDATA, &HFF ' mask all bits DEF SEG END SUB ----------------------------------------------
:
Bearbeitet durch User
Peter B. schrieb: > Was ist das zb für eine Meldung die ich nicht verstehe? > ----------------------------------- > .model medium,basic > .code > .286 > > public pcopykl > pcopykl proc SegAddr:DWord, ofs:DWord > > mov ax,[WORD SegAddr] > mov bx,[WORD ofs] > ret > pcopykl Endp > > End > ----------------------------------- Wieder so ein Beispiel für eine "andere Frage" - bleib bei deiner 1. Frage in diesem Post - sonst verwirrst du nur jeden der dir helfen will und du hast schon wieder - ich glaub jetzt das 5. mal keine meiner Fragen beantwortet so macht das keinen Spass
4 Frage == 4 Antworten 1. Was ist VGA-MX - ModeX? 2. du willst diese yPAGECOPY Routine nach ASM portieren? 3. Funktioniert denn dieser Basic-Code? 4. Ist das schon die ganze Zeit dein Ziel?
Die Frage kam kurz vorher: ---------------------------------- z.B. 1. Ich hab immer noch keine Ahnung warum du NUR DWord übergeben kannst??? --------------------------------- Darum eine Antwort, in längerer Form, die ich eigentlich vermeiden wollte. Dieser Inhalt war ja in meiner Hauptfrage, mehr wollte ich nicht. Es kamen dann immer neue Antworten.....das es jetzt soviel wurde ohne den Kern zu treffen. --------------------------------- public pcopykl pcopykl Proc SegAddr:DWord , ofs:DWord lds si,.... ... ... ret pcopykl Endp ---------------------------------- Ich war schon fast am Ziel (siehe Bild mit Fehlermeldung): mov ax,[WORD SegAddr] Danke.
:
Bearbeitet durch User
------------------------ 3. Funktioniert denn dieser Basic-Code? ------------------------ Der Funktioniert, aber die For-Schleife ist mir zu langsam. Danke. Hier mal der ganze original Demo-Code, wenn es sein muss : ----------------------------------------- DECLARE sub pcopykl CDECL (byval a&, byval b&) DECLARE sub pcopygr CDECL (byval a&, byval b&) DECLARE SUB ySCREEN() declare SUB yPSET (x AS INTEGER, y AS INTEGER, c AS INTEGER) declare SUB yCLS (c AS INTEGER) declare FUNCTION yPOINT% (x AS INTEGER, y AS INTEGER) declare SUB yPAGEWORK (pageNum AS INTEGER) declare SUB yPAGEFLIP (pageNum AS INTEGER) declare SUB yPAGECOPY (dstPage AS INTEGER, srcPage AS INTEGER) CONST scINDEX = &H3C4 CONST scMapMask = 2 CONST scDATA = &H3C5 CONST scSequencerMemoryMode = 4 CONST gcINDEX = &H3CE CONST gcDATA = &H3CF CONST gcBitMask = 8 CONST gcReadMapSelect = 4 CONST gcGraphicsMode = 5 CONST gcMiscellaneous = 6 CONST crtcStartAddressHigh = 12 CONST crtcStartAddressLow = 13 CONST crtcUnderlineLocation = 20 CONST crtcModeControl = 23 CONST crtcINDEX2 = &H3D4 CONST crtcDATA2 = &H3D5 DIM SHARED yPageSeg AS INTEGER dim shared wert as string yPageSeg = &HA000 call yscreen do wert$=input$(1) if wert="q" then screen 0 call yscreen call ypagework(1) for g%=0 to 180 call ypset(g%,g%,12) next g% call ypagework(2) for g%=0 to 300 call ypset(g%,45,14) next g% call ypagework(3) for g%=0 to 300 call ypset(g%,120,13) next g% end if if wert="a" then for z%=0 to 10 call ypageflip(1) call ypageflip(2) call ypageflip(3) next z% end if if wert="s" then for z1%=0 to 10 call yPAGECOPY(0,1) call yPAGECOPY(0,2) call yPAGECOPY(0,3) next z1% end if if wert="z" then call ypagework(0) call ycls(14) end if loop SUB yPAGECOPY (dstPage AS INTEGER, srcPage AS INTEGER) DIM ofs AS LONG DIM segm AS LONG OUT scINDEX, scMapMask OUT scDATA, &HF OUT gcINDEX, gcBitMask OUT gcDATA, &H0 IF (dstPage < srcPage) THEN ofs = CLNG(srcPage - dstPage) * 16000 segm= &HA000 + dstPage * 1000 call pcopykl(segm,ofs) ELSE ofs = CLNG(dstPage - srcPage) * 16000 segm= &HA000 + srcPage * 1000 call pcopygr(segm,ofs) END IF OUT gcDATA, &HFF END SUB SUB yPAGEFLIP (pageNum AS INTEGER) DIM adr AS STRING adr = LEFT$(MKL$(CLNG(pageNum) * 16000), 2) DO: LOOP WHILE (INP(&H3DA) AND 1) OUT crtcINDEX2, crtcStartAddressHigh OUT crtcDATA2, ASC(RIGHT$(adr, 1)) OUT crtcINDEX2, crtcStartAddressLow OUT crtcDATA2, ASC(LEFT$(adr, 1)) DO: LOOP UNTIL (INP(&H3DA) AND 8) END SUB SUB yPAGEWORK (pageNum AS INTEGER) yPageSeg = &HA000 + pageNum * 1000 END SUB FUNCTION yPOINT% (x AS INTEGER, y AS INTEGER) OUT gcINDEX, gcReadMapSelect OUT gcDATA, x AND 3 DEF SEG = yPageSeg yPOINT% = PEEK(x \ 4 + y * 80) DEF SEG END FUNCTION SUB yCLS (c AS INTEGER) OUT scINDEX, scMapMask OUT scDATA, &HF DEF SEG = yPageSeg FOR i% = 0 TO 15999 POKE i%, c NEXT i% DEF SEG END SUB SUB yPSET (x AS INTEGER, y AS INTEGER, c AS INTEGER) OUT scINDEX, scMapMask OUT scDATA, 2 ^ (x AND 3) DEF SEG = yPageSeg POKE (x \ 4 + y * 80), c DEF SEG END SUB SUB ySCREEN SCREEN 13 ' Disable chain-4 mode OUT scINDEX, scSequencerMemoryMode OUT scDATA, &h06 ' Turn off odd/even and set write mode 0 OUT gcINDEX, gcGraphicsMode OUT gcDATA,&h40 ' Disable chain OUT gcINDEX, gcMiscellaneous OUT gcDATA, &h05 ' Disable long mode OUT crtcINDEX2, crtcUnderlineLocation OUT crtcDATA2, &h00 ' Enable byte mode OUT crtcINDEX2, crtcModeControl OUT crtcDATA2, &he3 END SUB ----------------------------------- Diese beiden in ASM ersetzen die For-Schleife in "SUB yPAGECOPY": DECLARE sub pcopykl CDECL (byval a&, byval b&) DECLARE sub pcopygr CDECL (byval a&, byval b&)
:
Bearbeitet durch User
Um noch weiter zu gehen habe ich diese Schleife in Turbo C 2.0 und die Funktioniert. Turbo C benutzt dann automatisch den TASM der im Ordner liegen muss. Dieses OBJ lese ich dann in PDS Basic so ein , weil es von C kommt: DECLARE sub pcopykl CDECL (byval a&, byval b&) DECLARE sub pcopygr CDECL (byval a&, byval b&) ----------------------------------------------------------- void far pcopykl (long v_segment, long ofs) { asm Push DS; asm Push SI; asm mov ax,v_segment; asm mov ds,ax; asm mov ax,ofs; asm mov si,ax; asm mov ax,v_segment; asm mov es,ax; asm mov ax,0; asm mov di,ax; asm mov cx,15999 ; gehe: asm mov Al,ds:[SI]; asm mov es:[di],al; asm Add SI,1; asm Add di,1; asm loop gehe; asm Pop SI; asm Pop DS; } ------------------------------------------------------- Darum wollte ich direkt in TASM die LONG übergeben, was aber da nicht funktioniert. --------------------------- long v_segment, long ofs --------------------------- Danke
:
Bearbeitet durch User
eine alternative Lösung
1 | .model medium,basic |
2 | .code |
3 | .286 |
4 | |
5 | public pcopykl |
6 | pcopykl proc SegAddr:word, dumy1:word, |
7 | ofs:word, dumy2:word |
8 | push DS |
9 | mov AX,SegAddr ;lowword als seg |
10 | mov DS,AX |
11 | mov SI,ofs ;lowword als Index |
12 | .... ;DS:SI hat nun die Addresse |
13 | ....
|
14 | pop DS |
15 | ret
|
16 | pcopykl Endp |
17 | End
|
Übergabe als Long ausgewertet wird jeweils nur das Low word.
:
Bearbeitet durch User
Peter B. schrieb: > Wo gibt es denn bitte aufklärende kleine Lektüre für den TASM (DOS) als > PDF in deutsch? > > Danke. Wie wäre es z.B. hiermit: https://www.borncity.com/web/Library/EinfASM.pdf Zwar als html, aber auch komplett gezipped runterladbar: http://andremueller.gmxhome.de/ http://andremueller.gmxhome.de/bastut.zip
Danke für den Tip. Die Idee ist gut. Meine ASM wird compiliert mit deinem Vorschlag. Die VGA-Screens werden aber noch nicht kopiert vom dem OBJ-Programm. Komisch ist das das ASM von Turbo C 2.0 mit TASM geht und die Obj funktioniert. Danke.
:
Bearbeitet durch User
Peter B. schrieb: > Komisch ist das das ASM von Turbo C 2.0 mit TASM geht und die Obj > funktioniert. dann lass dir den Assembler Code ausgeben und schau was dort passiert. Der Inline Assembler ist bei weitem kein vollständiger Ersatz für TASM
Gibt es für den X86 eine freie Software in Windows10 um den x86 zu emulieren? Danke
----------------------------- Der Inline Assembler ist bei weitem kein vollständiger Ersatz für TASM ----------------------------- Dieses Turbo C hat keinen Inline-ASM eingebaut , dieses Turbo C ruft den TASM auf. Wenn der nicht im TC-Ordner ist, meckert das Turbo C.
Peter B. schrieb: > Dieses Turbo C hat keinen Inline-ASM eingebaut , dieses Turbo C ruft den > TASM auf. Wenn der nicht im TC-Ordner ist, meckert das Turbo C. Natürlich hat es das oder was glaubst du was das asm Schlüsselwort macht? Zu c gehört es jedenfalls nicht. Warum stellst du immer alles in Frage?
Peter B. schrieb: > Gibt es für den X86 eine freie Software in Windows10 um den x86 zu > emulieren? > > Danke IDA oder beim kompilieren Assemblerlisting Ausgabe einschalten - irgendwo in den Optionen oder Kommandozeile
cppbert schrieb: >> Gibt es für den X86 eine freie Software in Windows10 um den x86 zu >> emulieren? und Dosbox - oder was meinst du mit "emulieren"
Danke habe jetzt den IDA geladen. Erfüllt das was ich brauche.
Peter B. schrieb: > Danke habe jetzt den IDA geladen. Ob du damit weiter kommst bezweifele ich, denn ich denke, dass dein Ansatz grundsätzlich falsch ist. Assemblerfunktionen, die mit Parameter(n) von Hochsprachen aus aufgerufen werden, bekommen diese (fast immer)auf dem Stack übergeben. Ich sehe keine Stackoperationen (Stichwort Stackframe) in den Programmfragmenten. In der oben genannten Literatur zeigt Günter Born dazu ein kurzes Beispiel. Dort ruft zwar Pascal eine Assemblerfunktion auf, aber die Technik ist in anderen Umgebungen sehr ähnlich. Übrigens gab es von Microsoft ein kleines Heftchen zum Makroassembler: Mixed-Language Programming Guide. Dort wird diese Thematik sehr ausführlich behandelt. Möglicherweise ist im Netz ja etwas zu finden.
G. O. schrieb: > Ich sehe keine Stackoperationen > (Stichwort Stackframe) macht er schon - nur eben nicht von Hand test PROC Var:WORD mov ax,Var generiert den Stackframe Access Code für die 1. Variable
cppbert schrieb: > G. O. schrieb: >> Ich sehe keine Stackoperationen >> (Stichwort Stackframe) > > macht er schon - nur eben nicht von Hand > > test PROC Var:WORD > mov ax,Var > > generiert den Stackframe Access Code für die 1. Variable
cppbert schrieb: > cppbert schrieb: >> G. O. schrieb: >>> Ich sehe keine Stackoperationen >>> (Stichwort Stackframe) >> >> macht er schon - nur eben nicht von Hand >> >> test PROC Var:WORD >> mov ax,Var >> >> generiert den Stackframe Access Code für die 1. Variable 1. Parameter
cppbert schrieb: > macht er schon - nur eben nicht von Hand > > test PROC Var:WORD > mov ax,Var > > generiert den Stackframe Access Code für die 1. Variable Ok, hab´ ich verstanden. Das ist TASM-Syntax mit der ich noch nie zu tun hatte. Dann will ich ´mal die Gelegenheit nutzen, mein erstes TASM-Programm, die Frage ganz am Anfang betreffend, zu schreiben. Es ging ja wohl darum, einen Speicherbereich von Quelle nach Ziel zu kopieren. Das aufrufende Programm muß natürlich Quelle und Ziel als 32-Bit Werte übergeben. Außerdem müßten noch, vermute ich, irgendwelche public bzw extern Deklarationen oder (Speicher)Modellangaben ergänzt werden. Wenn nicht, um so besser. Das Programm ist für eine 16-Bit Umgebung gedacht.
1 | PROC memcpy near quelle:dword, ziel:dword, len:word |
2 | uses es,di,ds,si,cx |
3 | lds si, [quelle] ;initialisation |
4 | les di, [ziel] |
5 | mov cx, [len] |
6 | ;hier direction-flag setzen |
7 | rep movsb ;es werden byte kopiert und.. |
8 | ret ;..fertig |
9 | ENDP memcpy |
Man mag mich korrigieren.
G. O. schrieb: > Dann will ich ´mal die Gelegenheit nutzen, mein erstes TASM-Programm, > die Frage ganz am Anfang betreffend, zu schreiben. Peter hat es unklar formuliert, er will Segment und Offset, beides 16 bit von PDS Basic in ein TASM proc bringen Problem: PDS Basic kennt keine unsigned 16, 32 bit Typen, also wollte er Segment und Offset jeweils als 32Bit signed long Wert runter bringen aber davon jeweils nur den unteren Word-Anteil nutzen, damit er imd Basic Programm schön im positiven Wertebereich bleiben kann
Danke für die Hilfe. ----------------------- public pcopykl pcopykl Proc SegAddr:DWord , ofs:DWord lds si,.... ... ... ret pcopykl Endp ----------------------- SegAddr:DWord und ofs:DWord müssen in "lds si,...." reinpassen oder mit umwandeln in "mov ds,..." und "mov si,..." beide müssen immer nur die ersten beiden Byte haben vom DWord. "lds si,v_segment:ofs" das funktioniert leider nicht. Danke.
:
Bearbeitet durch User
Hier noch Mal eine andere Lösung
1 | .model medium,basic |
2 | .code |
3 | .286 |
4 | |
5 | public pcopykl |
6 | pcopykl proc SegAddr:dword, ofs:dword |
7 | push DS |
8 | push ES |
9 | mov AX,wordptr SegAddr |
10 | mov DS,AX |
11 | mov ES,AX |
12 | mov SI,wordptr ofs ; src SegAdr:ofs |
13 | mov DI,0 ; dest SegAdr:0 |
14 | mov CX,15999 |
15 | cld ; Richtung löschen |
16 | ;test CX,1 ; hier unnötig |
17 | ;jz L1 |
18 | movsb
|
19 | L1: |
20 | shr CX,1 |
21 | rep movsw |
22 | pop ES |
23 | pop DS |
24 | ret
|
25 | pcopykl Endp |
26 | End
|
Diese Variante sollte deinem C Inline Beispiel entsprechen mit Ausnahme des 16bit movsw. Beachte die dword Deklaration geladen werden die Parameter via wordptr und damit die unteren16bit. Die Routine funktioniert nur wenn sich Quelle und Ziel nicht überlappen. Es reicht die Segment Register zu sichern.
:
Bearbeitet durch User
Vielen Dank. Dein Muster funktioniert wunderbar. Das werde ich als Grundmuster nehmen auch für andere Copy/Dinge in ASM. Danke.
Du musst uns langsam mal erzählen was du so vor hast: TC (mit Inline-ASM) Turbo Pascal (mit Inline-ASM) PDS Basic und alles noch mit TASM vermischt willst du dich einfach durch alle relevanten Kompiler der damaligen Zeit durcharbeiten oder suchst du noch das richtige Werkzeug für deinen "grossen" Plan?
Ich suche nach einem richtigen Werkzeug für meine Spielerei. Möchte kleine Spiele selber entwerfen in VGA-Grafik. Dabei brauche ich zwischen den Basicbefehlen schnelle Routinen die ich begreife für Sprite und andere Sachen. Brauche mehrere Grafikseiten in VGA , es bietet sich das VGA-Modex an(funktioniert in PDS). Weiterhin bieten sich mehrere Arrays an in PDS($dynamic), die bis zu 64000Byte haben. Kann in PDS mehrere EXE starten (Chain) und dazwischen umschalten. Kann jetzt auch in ein $dynamic-Array(PDS) wie in VGA zeichnen usw und dann nach VGA copieren. Sind alles wunderbare Dinge. Das alles ist für mich schwierig von Pascal 6.0 aus und auch in Turbo C ist es nicht einfach. Ich mag das PDS Basic , es ist sehr mächtig. Danke.
Peter B. schrieb: > Ich suche nach einem richtigen Werkzeug für meine Spielerei. >... > Das alles ist für mich schwierig von Pascal 6.0 aus und auch in Turbo C > ist es nicht einfach. > > Ich mag das PDS Basic , es ist sehr mächtig. deine bisherigen Beispiele hier sehen in Turbo Pascal, C oder PDS Basic fast gleich aus - ich sehe da jetzt nicht so viel wo PDS Basic besser ist - ausser das es dir vielleicht von der Syntax her eher zusagt Ich würde bei Turbo C/TASM bleiben - da findest du auch viel mehr Beispiele und die Leute können einfacher helfen
Wenn es wirklich auf max Speed ankommt, würde ich ev darüber nachdenken auf movsd zu setzen. Dazu must du dann aber auf .386 umschalten damit movsd verstanden wird. Dazu noch passende movsb Befehle einstreuen falls der Zähler nicht durch 4 teilbar ist. Das Nonplusultra wäre den Zähler als Parameter mitzuführen. Zusätzlich sind lokale Labels mit @L1 ganz hilfreich wenn es mehrere Funktionen im ASM File gibt
Thomas Z. schrieb: > Wenn es wirklich auf max Speed ankommt, würde ich ev darüber > nachdenken > auf movsd zu setzen. Dazu must du dann aber auf .386 umschalten damit > movsd verstanden wird. Dazu noch passende movsb Befehle einstreuen falls > der Zähler nicht durch 4 teilbar ist. > Das Nonplusultra wäre den Zähler als Parameter mitzuführen. Zusätzlich > sind lokale Labels mit @L1 ganz hilfreich wenn es mehrere Funktionen im > ASM File gibt er hat nur einen 8086
cppbert schrieb: > er hat nur einen 8086 Dann wäre auch .286 falsch da es zum Beispiel ein pusha erlauben würde was auf einem 8086 nicht implementiert ist.
Peter B. schrieb: > Ich mag das PDS Basic... Also dann hier das ultimative Buch zur diskutierten Problematik: http://antonis.de/qbebooks/btubook.zip Im letzten Kapitel wird der Anschluss von Assemblerprogrammen an Qbasic und Basic PDS in wirklich epischer Breite behandelt. Allerdings sollte man des Englischen einigermaßen mächtig sein.
:
Bearbeitet durch User
Ich kann auf 386-Modus umschalten. Danke.
:
Bearbeitet durch User
Hallo, guten Tag. Wo steck man bitte eigentlich hier 2 Festwerte hin , die man nachher zum Rechnen brauch? Die Festwerte bleiben in der ASM immer drin. --------------------- public pcopykl pcopykl Proc SegAddr:DWord , ofs:DWord lds si,.... ... ... ret pcopykl Endp ----------------------- Danke
Festwerte setzen ist gelöst. Wusste nicht, das es so einfach ist diese reinzusetzen. Danke.
:
Bearbeitet durch User
Danke für die btubook.zip Da sind viele interessante Dinge drin für PDS-Basic
Hallo, guten Tag. Wie kann man bitte dieses Kopieren mit 64000Byte von A nach B total auf Maxi-Copy bringen? Ich kann auch auf den 386 umschalten den MiSTer-Core(PC) Danke.
1 | .model medium,basic |
2 | .code |
3 | .386 |
4 | |
5 | public vgacopy |
6 | vgacopy proc segadr:word, ofadr:word, segadr1:word, ofadr1:word |
7 | push DS |
8 | push ES |
9 | |
10 | mov AX,SegAdr |
11 | mov DS,AX |
12 | |
13 | mov AX,SegAdr1 |
14 | mov ES,AX |
15 | |
16 | mov SI,ofadr |
17 | mov DI,ofadr1 |
18 | |
19 | mov CX,64000 |
20 | cld |
21 | movsb |
22 | |
23 | shr CX,1 |
24 | rep movsw |
25 | |
26 | pop ES |
27 | pop DS |
28 | ret |
29 | vgacopy Endp |
:
Bearbeitet durch User
Es gibt movsb = cx = bytes movsw = cx = words movsd ab 386 = cs = dwords d.h. bei movsd musst du nur 64000/4=16000 in cx rein schreiben und dann eben NUR mit movsd arbeiten info: shr CX,1 ist wie durch 2 shr CX,2 ist wie durch 4 da du aber eh immer fest 64000 bytes transferieren willst würde ich einfach 16000 in cx setzen und fertig - keinen rechen mit shr oder vorher die movsb Sache
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.