Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

QB Arrays in ASM bearbeiten

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 17.08.2007, 19:09    Titel: QB Arrays in ASM bearbeiten Antworten mit Zitat

Hallo!
Ich will den Bilschirmspeicher in einem in QB definiertem Array mit einer Assembler-Routine (als Lib in QB geladen) speichern, bzw. das Array wieder in den Bildschirmspeicher zurückschreiben (Textmodus 80 x 25). Ich bin absoluter Assembler Anfänger (was an meinem Versuch unterhalb wahrscheinlich erkennbar ist happy )

So sieht die Routine in QB aus, ist jedoch zu langsam (und nebenbei verbraucht Sie den doppelt so viel Speicher, als nötig wäre; integer --> 2Byte, 1Byte wird gespeichert))
Code:

'Array in dem Bildschirm gespeichert wird:
DIM SHARED Bild(0 TO 3999) AS INTEGER
DEF SEG = &HB800      'Grafikspeicher
FOR q = 0 TO 3999      'Bytes einzeln aus Bildschirm-Speicher lesen...
  Bild(q) = PEEK(q)      '...und in Array schreiben
NEXT


Mein Versuch das Ganze in Assembler zu realisieren (Überschreibt jedoch bei einer Ausführung irgendetwas im Speicher und DOS stürzt ab traurig )
Code:

.MODEL medium,basic
.386
.STACK 100h
.CODE

;***********************************************************************
; SUB SaveScreen (BYVAL ArraySeg AS INTEGER, BYVAL ArrayOffs AS INTEGER)
;***********************************************************************
PUBLIC SaveScreen
SaveScreen PROC
  ; 08  Array Offset
  ; 06  Array Segment
  ; 04  Basic segment
  ; 02  Basic offset
  ; 00  BP
 
  PUSH BP
  MOV BP,SP
;Arraysegment nach DS, ArrayOffset nach AX 
  MOV AX,[BP+6]
  MOV DS, AX
  MOV AX,[BP+8]
  MOV SI, AX

;Textsegement nach ES
  MOV BX, 0B800H
  MOV ES, BX
  MOV BX, 0000H
  MOV DI, BX

  NextByteSave:
  MOV CX, ES:[DI]
  MOV DS:[SI], CX
  INC DI
  INC SI
  CMP DI, 0F9FH
  JBE NextByteSave
 
  POP BP
  RET
SaveScreen ENDP

END


Der Aufruf der obigen Assembler Sub (in Lib) von QB:
Code:

DECLARE SUB SaveScreen (BYVAL ArraySeg AS INTEGER, BYVAL ArrayOffs AS INTEGER)
DIM SHARED Bild(0 TO 3999) AS INTEGER

SaveScreen VARSEG(Bild(0)), VARPTR(Bild(0))


Warum funktioniert das so nicht?
Weche Verbesserungsvorschläge habt Ihr für das Programm?
(Hab' das Grundgerüst der SUB übrigens von der DirectQB-Lib, Code von mir)

Danke im Voraus, St_W
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 18.08.2007, 21:57    Titel: Antworten mit Zitat

Es gibt z.B. diese Assembler-Library, die Routinen zum Speichern und Wiederherstellen des Bildschirminhalts enthält, auch als ASM-source: ASMWIZ31

Kann hier heruntergeladen werden: http://www.tgh3.com/

Georg
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 18.08.2007, 22:12    Titel: Antworten mit Zitat

Zu Deinem Code noch folgende Bemerkung:

1. man kann den Bildschirminhalt auch in einer String Variable speichern

2. statt der NextByteSave Schleife kann man auch einfach schreiben:
cld ;vorwärts
mov cx,4000 ;verschiebe 4000 byte
rep movsb ; verschiebe byte, wiederhole cx-mal

Georg
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
csde_rats



Anmeldungsdatum: 07.01.2007
Beiträge: 2292
Wohnort: Zwischen Sessel und Tastatur

BeitragVerfasst am: 18.08.2007, 22:17    Titel: Antworten mit Zitat

Georgp24 hat Folgendes geschrieben:
man kann den Bildschirminhalt auch in einer String Variable speicherng
Es sei angemerkt, dass QB-Strings maximal 32 KB groß sind - der bildschirm ist höchstwahrscheinlich grösser...
_________________
If hilfreicher_Beitrag then klick(location.here)

Klick
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 18.08.2007, 22:27    Titel: Antworten mit Zitat

Der Textscreen ist genau 4000byte groß... Und im ersten Post steht ja was von 80x25...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
ytwinky



Anmeldungsdatum: 28.05.2005
Beiträge: 2624
Wohnort: Machteburch

BeitragVerfasst am: 19.08.2007, 22:55    Titel: Antworten mit Zitat

IIRC wird auf dem Bildschirm(auch im Text-Modus) ein zweites Byte benutzt, damit zum Zeichen auch Farben dargestellt werden können. 80x25=2000. Wenn also das 1.Byte das Zeichen ist(&hB800), wäre das 2. Byte(also &hB801) das Farbbyte. Damit erhöht sich natürlich die zu speichernde Menge erheblich, bleibt mit 4000 Byte aber immer noch deutlich unter 32KB.
Inwieweit da auch noch andere Angaben enthalten sind, weiß ich nicht mehr.
Schön, daß es WikiPedia gibt Ja! happy
[Edit]
Gut, daß ich mir mit 'oder ich..' noch ein Hintertürchen offengelassen hatte zwinkern
Ich habe diesen Beitrag, entsprechend dem Einwand von Georgp24, geändert.. verlegen
_________________
v1ctor hat Folgendes geschrieben:
Yeah, i like INPUT$(n) as much as PRINT USING..
..also ungefähr so, wie ich GOTO..

Zuletzt bearbeitet von ytwinky am 20.08.2007, 16:38, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 20.08.2007, 08:09    Titel: Antworten mit Zitat

Also 80x25 sind 2000 Byte und durch das zweite Byte ergeben sich 4000.

Georg
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 20.08.2007, 11:09    Titel: Antworten mit Zitat

Danke für eure schnellen Antworten...

Der Ansatz, alles in einem String zu speichern, gefällt mir gut.
Wie realisiere ich das jetzt in Assembler?
in QB muss ich wahrscheinlich dann statt
DIM Bild(0 to 3999) AS INTEGER
DIM Bild AS STRING * 4000
verwenden. Ist das so richtig? Damit wäre der doppelte Speicherverbrauch schon beseitigt.
Wie die ASM-Routine dazu aussehen soll, davon habe ich keine Ahnung. Vielleicht kann mir das jemand genauer erklären.

Übrigens, zum Bildschirmspeicher im 80x25 Textmodus (SCREEN 0):
80 Spalten * 25 Zeilen mit jeweils einem ASCII-Zeichen(1 Byte) ergeben 2000 Bytes, dazu wird noch die Textfarbe (4-Bits) , die Hintergrundfarbe (3-Bits) und ein Blinkend-Bit (1-Bit) für jedes Zeichen gespeichert, also wieder (4+3+1=8 Bits, 1Byte) * 80 * 25 ergeben 2000 Bytes. Und diese werden nacheinander gespeichert, also ein Zeichen, dann ein Farbattribut, ein Zeichen, ... insgesamt 4000 Bytes!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 20.08.2007, 22:43    Titel: Antworten mit Zitat

Code:

'Ich habe das Bildschirminhalt-Speichern und -Wiederherstellen mal mit
'dem QuickBasic Inline-Assembler gelöst ;)
'die Function Blockcpy$ stammt aber nicht von mir, sondern von
'Rick Elbers
'Man kann damit auch Teile des Bildschirms kopieren bzw. jeden Speicher-
'bereich unter 1 MB.
'
'Georg
'
'
DECLARE FUNCTION BLOCKCPY$ ()          'aligned blockcopy

CLS
COLOR 15, 4
PRINT "First Screen"
COLOR 7, 0

DEFINT A-Z

CPY$ = BLOCKCPY$

SRCSEG = &HB800: SRCOFF = 0
DIM SMS AS STRING * 4000 'SMS = Save my screen
SMSSEG = VARSEG(SMS$): SMSOFF = VARPTR(SMS)

CALL ABSOLUTE(BYVAL (SRCSEG), BYVAL (SRCOFF), BYVAL (SMSSEG), BYVAL (SMSOFF), 4000, SADD(CPY$))

DEF SEG

PRINT "Press a key to clear screen": SLEEP

CLS

PRINT "Press a key to restore screen": SLEEP

CALL ABSOLUTE(BYVAL (SMSSEG), BYVAL (SMSOFF), BYVAL (SRCSEG), BYVAL (SRCOFF), 4000, SADD(CPY$))

DEF SEG

END

DEFSTR A-Z
'ASSEMBLY IN QBASIC 9: .386 CODING.(rick@tip.nl)
FUNCTION BLOCKCPY
'-----------------------------------------------------------
'This is an aligned blockcopy which makes use of
'Paul Hsiehs align method and .386 coding

'STACKPASSING: BYVAL(SRCSEG),BYVAL(SRCOFF)


'              BYVAL(DESTSEG),BYVAL(DESTOFF),NROFBYTES


'-----------------------------------------------------------
''SET UP STACKFRAME
ASM = ASM + CHR$(&H55)                              'PUSH BP
ASM = ASM + CHR$(&H89) + CHR$(&HE5)                 'MOV BP,SP
ASM = ASM + CHR$(&H1E)                              'PUSH DS
ASM = ASM + CHR$(&H6)                               'PUSH ES
'GET LEN POINTER FROM THE STACK
ASM = ASM + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)  'MOV BX,[BP+06]>LEN
'LOADS SOURCE TO DS[SI], DEST TO ES[DI], LEN TO CX
ASM = ASM + CHR$(&HC4) + CHR$(&H7E) + CHR$(8)       'LES DI,[BP+8]
ASM = ASM + CHR$(&H8B) + CHR$(&HF)                  'MOV CX,[BX]
ASM = ASM + CHR$(&HC5) + CHR$(&H76) + CHR$(&HC)     'LDS SI,[BP+C]
'ALIGN THE START OF THE COPYROUTINE TO ES[DI]MOD 4 =0
ASM = ASM + CHR$(&H89) + CHR$(&HC8)                 'MOV AX,CX
ASM = ASM + CHR$(&H29) + CHR$(&HF9)                 'SUB CX,DI
ASM = ASM + CHR$(&H29) + CHR$(&HC1)                 'SUB CX,AX
ASM = ASM + CHR$(&H81) + CHR$(&HE1) + MKI$(&H3)     'AND CX,3
ASM = ASM + CHR$(&H29) + CHR$(&HC8)                 'SUB AX,CX
ASM = ASM + CHR$(&H7E) + CHR$(13)                   'JLE +13 ONLY_ENDBYTES
'COPY THE FIRST BYTES LEFT OVER WITH MOVSB
ASM = ASM + CHR$(&HF3) + CHR$(&HA4)                 'REP MOVSB
'ALIGN THE NUMBER OF BYTES FOR MAIN COPYLOOP TO LEN MOD 4=0
ASM = ASM + CHR$(&H89) + CHR$(&HC1)                 'MOV CX,AX
ASM = ASM + CHR$(&H25) + CHR$(&H3) + CHR$(&H0)      'AND AX,3
ASM = ASM + CHR$(&HC1) + CHR$(&HE9) + CHR$(2)       'SHR CX,2 <386
'MAIN COPY LOOP WITH THE BLAZE OF MOVSD
ASM = ASM + CHR$(&HF3) + CHR$(&H66) + CHR$(&HA5)    'REP MOVSD< 386
'END_BYTES: COPY THE LEFT OVER BYTES WITH MOVSB
ASM = ASM + CHR$(&H1) + CHR$(&HC1)                  'ADD CX,AX
ASM = ASM + CHR$(&HF3) + CHR$(&HA4)                 'REP MOVSB
'WE ARE DONE :RETURN TO QBASIC
ASM = ASM + CHR$(&H7)                               'POP ES
ASM = ASM + CHR$(&H1F)                              'POP DS
ASM = ASM + CHR$(&H5D)                              'POP BP
ASM = ASM + CHR$(&HCA) + MKI$(10)                   'RETF A

BLOCKCPY = ASM

END FUNCTION


Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz