Ram allocation (ASM)

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Ram allocation (ASM)

Beitrag von oDOSseus »

Hallo liebes DOS-Forum!

Nach vielen langen Jahren in der Versenkung, bin ich mal wieder am Programmieren für DOS.

Ich habe noch nie zuvor RAM alloziiert in DOS und irgendwie gibt es da Probleme.
Ich fordere bsp. 100 byte an. Das macht nach meiner Rechnung 7 Paragraphen. Also BX=7, AH=48h und int21 ausführen. Da ich zwei solcher Blöcke brauche, mache ich das nochmal. Ich stelle aber enttäuscht fest, dass die zurückgegebenen Adressen sich nur um 7 unterscheiden. Sprich: Adresse2-Adresse1=7. Aber ich habe doch 7 Paragraphen und nich 7 byte angefordert. :-(

Code: Alles auswählen

mov    bx,    7
mov    ah,    $48
int    $21
mov    [addr1],    AX
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

Und ist das nicht der Segment-Anteil?

EDIT: Grad nachgelesen - da wird der Segment-Anteil zurück gegeben. Dann passt es doch. Ein Segment = 16 Bytes = 1 Paragraph.

Deine Adresse wäre also z. B.:

mov es,ax
mov ...,[es:$0000] 1. Byte
mov ...,[es:$0001] 2. Byte
.
.
.
mov ...,[es:$0006] 7. Byte
usw. usw.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: Ram allocation (ASM)

Beitrag von oDOSseus »

Ich will ja die Adresse des blocks den ich bekam speichern. das füllen mach ich woanders, indem ich

Code: Alles auswählen

mov    bx,    [addr]
xor    si,    si  
....
mov    [bx+si],    $12   
....
mache
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

Ich fürchte das Problem ist, dass Du nicht sicher sein kannst, woher DOS den RAM-Bereich nimmt. Dein Source wird so nicht funktionieren. Brauchst Du immer den selben Speicher (Größe) ? Falls ja, dann leg den Bereich doch im Source / Code mit ab. Also beispielsweise:

.
.
.
mein_ram: dup 7*16 db $00

oder so in der Art.

Ansonsten wäre deine vollständige Adresse auf den Block $<segment das du zurück erhalten hast>:$0000. Also, du musst deinen Code dahingehend anpassen, dass das Segment des Bereichs variabel, und der Offset bei $0000 beginnt.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: Ram allocation (ASM)

Beitrag von oDOSseus »

Es muss variable sein. Kannst du mir eventuell einen beispiel-code geben?
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

also, wenn du deinen Block zum Beispiel füllen möchtest - wir gehen mal davon aus, die DOS-Funktion hat dir in AX nun das Segment der Paragraphen zurück gegeben, das Du reserviert hast:

mov [addresse],ax ; merken des reservierten Bereiches.
push ds ; DS merken

mov es,ax
mov ds,ax
xor si,si
mov di,$0001
mov cx,(paragraphen*16 )- 1
mov byte [si],$füllbyte
cld
rep movsb ; Der Adressbereich ist jetzt gefüllt mit $Füllbyte

pop ds ; DS wieder herstellen.


Damit würdest Du den Speicherbereich z. B. mit einem beliebigen Byte füllen. Wenn Du mir sagst, was du vorhast, kann ich ggf. ein besseres Beispiel schreiben :-)
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

Das Ansprechen ist dann eigentlich auch selbsterklärend:

mov es,[addresse] ; Du kannst natürlich auch ein anderes Seg-Reg. nehmen

mov al,[es:$010] ; Das 17. Byte nach AL kopieren...
mov byte [es:$0000],$FF ; 255 in das erste Byte schreiben...

usw.

Und du kannst auch SI, DI und BX als Offset nutzen / Kombinieren. Wie gehabt. Der Unterschied ist eben, das [Addresse] eben nur den Segment-Anteil beinhaltet und deswegen nicht mehr als Offset genutzt werden kann. Also falsch:

mov bx,[adresse]
mov si,$0100
mov al,[si+bx]

Du weisst ja nie, welches Segment dir DOS zurück gibt. Wäre es beispielsweise $0300 (also eine korrekte Adresse von $0300:$0000), dann wäre nach dem obigen Beispiel

mov bx,$0300
mov si,$0100
mov al,bx+si also mov al,[DS:$0400] - was ein völlig anderer Speicherbereich ist (nicht nur wegen dem Offset-Anteil).

Richtig:

mov ds,[addresse]
mov bx,$0100
mov si,$0400
mov al,[bx+si] ; = Segment DS, Offset $0500, also das $501. Byte in deinem Speicherbereich.
Zuletzt geändert von Brueggi am Do 30. Okt 2014, 19:27, insgesamt 1-mal geändert.
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: Ram allocation (ASM)

Beitrag von oDOSseus »

nene das verstehe ich schon. dankeschön. probiere ich nachher mal aus.
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

Ok, ich bin leider nicht so der gute Erklärer :-) Ich hoffe, es hilft Dir weiter. Bei Fragen: Frag einfach :-)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: Ram allocation (ASM)

Beitrag von oDOSseus »

werd ich tun, danke =)
Benutzeravatar
oDOSseus
LAN Manager
Beiträge: 239
Registriert: Di 10. Aug 2010, 15:21

Re: Ram allocation (ASM)

Beitrag von oDOSseus »

Okay, also folgende Frage:

Wenn ich in21 mit AH=48h ausführe, dann ist doch AX die segment-adresse des neuen speicherbereichs. Und ich muss auch nur AX merken und wenn ich dann auf das erste byte zugreifen will, mach ich einfach:

Code: Alles auswählen

mov    [address],    ax
...
...
push   ds
mov    ds,    [address]
xor    si,    si
mov    al,    [si]    ;AL hat jetzt das erste byte aus dem speicherbereich
pop    ds
richtig?
Brueggi

Re: Ram allocation (ASM)

Beitrag von Brueggi »

Jep, so sollte das funktionieren. Da MS-DOS ja nur den Segment-Anteil zurück gibt, ist der Offset des 16-Byte-Blocks immer $0000. Anders macht es auch wenig Sinn und würde auch die Verwaltung von DOS wohl aufblähen ohne Ende.
Antworten