Daten auslesen in ASM aus einer Variable.

OP #7566760
Lesenswert?

Hallo, guten Tag. Frohen Weihnachtstag,

Ich habe hier eine kleine Demo für DOS:

DIM HUGE buff1(63999) as byte DIM bufseg1 as WORD bufseg1 = varseg(buff1(0))

DIM HUGE buff2(63999) as byte DIM bufseg2 as WORD bufseg2 = varseg(buff2(0))

! mov ax,bufseg1 ! push ax
! pop es

! mov cx,320 ! mov di,0 forloop:
! mov al,1 ! mov es:[di],al
! inc di
! loop forloop
....... .......

Ich lese 320x eine 1 ein in die Variable-Segment bufseg1. Es funktioniert auch. Wie kann ich jetzt bitte wieder die 320 Werte auslesen aus der bufseg1 und in bufseg2 rein in den nächsten Befehlen mit ASM?

Danke.

OP #7567392
Lesenswert?

Danke für die Info. Habe es jetzt geschafft:

Angangsdaten in bufseg1 rein. Daten aus bufseg1 raus und bei bufseg2 rein. Diese fs funktionniert nicht in Powerbasic 3.5

Es funktioniert. Weiß nicht wie man es einfacher machen kann ohne dauernd mit dem Wechsel in es.

1
DIM HUGE buff1(63999) as byte
2
DIM bufseg1 as WORD 
3
bufseg1 = varseg(buff1(0))
4

5
DIM  HUGE buff2(63999) as byte
6
DIM bufseg2 as WORD 
7
bufseg2 = varseg(buff2(0))
8

9
dim a as WORD 
10

11
a=0
12

13
!   mov es,bufseg1  
14
!   mov cx,40000
15
!   mov di,a
16
forloop:    
17
!   mov al,1    
18
!   mov  es:[di],al
19
!   inc  di  
20
!   loop  forloop  
21

22
!   mov cx,40000
23
!   mov di,a
24
forloop1:  
25
!   mov es,bufseg1    
26
!   mov  al,es:[di]
27

28
!   mov es,bufseg2      
29
!   mov  es:[di],al
30
!   inc  di  
31
!   loop  forloop1
(Firma: Funkenflug Industries) #7584931
Lesenswert?

Allerdings ist mir nicht klar, wie der Inhalt von CX in bi kommt, bi ist doch die Zählvariable. bi müsste mind. ein double sein, sonst kannst ja nur bis 255 zählen. Ich kenn sowas anders.

CX, (SI) und DI sind alle immer 16 Bit breit, kannst damit also von 0..65535 zählen. CX lässt sich in CL und CH aufgeteilt ansprechen, diese repräsentieren jeweils die unteren und oberen 8 Bits.

SI und DI lassen sich nicht so einfach aufteilen bzw. man muss sie dazu in ein anderes Register laden. Ihre Aufgabe beschreibt sich aus dem Namen. SI ist Source Index und DI ist Destination Index. LODSB z.B. lädt ein Byte von DS:[SI] in AL (die unteren 8 Bit von AX) und erhöht SI um 1. STOSB speichert ein Byte von AL in ES:[DI] und erhöht DI um 1.

#7588038
Lesenswert?

Purzel H. schrieb:

Der Befehl loop enthaelt ein dec-cx @ jumpnz, und ein vorheriges mov CX, 320 macht nachher 320 Durchgaenge

Diesen Befehlszusammenhang gab es früher gar nicht, da musste man sich die Schleifen von Hand zusammenstricken. Unabhängig davon wurden in professionellen Programmen mehr die rep-Goodies eingesetzt. Die Norton-Guides waren hervorragend, u.a. weil P.N auch viel mit BASIC referenzieren konnte, und so auch schnell programmiertechnische Zusammenhänge deutlich machen konnte.

(Firma: Funkenflug Industries) #7588430
Lesenswert?

Naja... doch schon. Ich habe durch mein Interesse an damaligen Computerviren in meiner Jugend recht viele Assemblerprogramme auseinandergepflückt und selbst geschrieben. Die Schleifen mit LOOP <blah> waren überall anzutreffen, genau wie die REP-basierten Wiederholungen z.B. REP SCASB, REP MOVSB oder auch REPZ/REPNZ. Gibt ja praktisch nichts woraus man nicht irgendwie eine Schleife basteln könnte und gerade bei Assembler wurde jeder dieser Kniffe auch irgendwo verwendet wenn es gerade ins Programm passt.

Oder wenn man Programme "optimiert" hat. XOR AX,AX ist beispielsweise zwei Byte kürzer als MOV AX,0 (müsste, XOR AX,AX ist glaube ich nur ein 8 Bit OpCode wenn ich mich korrekt erinnere) oder XCHG AX,CX ist ein Byte kürzer als MOV AX,CX.

#7589383
Lesenswert?

Rolf M. schrieb:

Genau sowas meinte ich mit "es gibt bestimmte Instruktionen, die sie auch für spezifische Zwecke nutzen". Deshalb ja auch nur "im Grunde".

Was man sich merken sollte, ist, dass frühere CP-Systeme oft nur ein Register hatten, den typischen "Akkumulator". Die Folge könnte sein, dass dann eben bestimmte Rechnungen über AX bevorzugt behandelt werden, bzw. schneller laufen. Ob das noch aktuell Sinn macht, sei mal dahin gestellt. Nette Lernhilfe ist eigentlich LEA (https://stackoverflow.com/questions/12869637/trouble-understanding-assembly-command-load-effective-address) wo auch nur die üblichen Verdächtigen (zum Zusammenrechnen) gehen.

(Firma: Funkenflug Industries) #7589434
Lesenswert?

LEA ist ja eigentlich nur ein Assembler-Hilfsmittel und kein echter Befehl, beim Assemblieren wird aus LEA SI,<label> ein MOV SI,<address>. Einer der Punkte, der das Disassemblieren von Programmen geringfügig erschwert, weil man erst ergründen muss, daß sowas z.B. mal ein LEA auf einen Puffer war. Viele Assembler erlauben auch sowas wie MOV SI,offset <label>, Ergebnis ist das Gleiche.

Register-Operationen sind alle sehr schnell, weil keinerlei Daten aus dem Speicher geholt oder hineingeschrieben werden müssen. Wenn man ein System mit langsamem Speicherzugriff hat, lohnt es sich natürlich, die Speicherzugriffe zu vermeiden.

Der Akkumulator ist so gut wie überall erforderlich, weil die Prozessoren sonst einfach sehr unflexibel werden. Ich finde Prozessoren mit ausschließlich einem Akkumulator ohne vollständigen Registersatz schon unflexibel. Deswegen bin ich bei µCs z.B. sehr schnell bei den AVRs gelandet, weil diese einen großen Register- und Befehlssatz bieten und nicht so eng genäht sind wie die PICs, die eher auf eine Programmierung mit Hochsprachen (C) optimiert zu sein scheinen. Da ist's egal was der Compiler aus dem Hochsprachenprogramm macht, aber kleiner und schneller (in der Ausführungsgeschwindigkeit) geht's natürlich mit dem AVR. Ansonsten bringt der Akkumulator schon viel für Rechenoperationen, beim x86 z.B. spielen AX und DX eine größere Rolle. Da muss man bei der Multiplikation oder Division den ersten Operanden ablegen und nach der Rechenoperation erhält man dort das Ergebnis. Andere Prozessoren verwenden die untersten Bytes des Arbeitsspeichers als Register-File (bspw. der 6502 mit seiner 256 Byte großen Zero Page, auf die der besonders schnell zugreifen kann), beim AVR bilden die ersten 32 Bytes ihres Speichers/Adressraumes den Registersatz, wobei das im Gegensatz zum x86 und 6502 eine Harvard-Architektur ist (getrennter Befehls- und Datenspeicher, wodurch auf beides gleichzeitig zugegriffen werden kann und daher kein Puffern von Daten im Prozessor erforderlich ist).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren