Thema: Base Pointer

Einzelnen Beitrag anzeigen

Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: Base Pointer

  Alt 5. Jan 2006, 20:19
Im 16-Bit Modus gibt es *NUR* die folgenden Adressierungsmodi:
Code:
    |               M o d                  |
R/M |    0    |       1      |       2      |
----+---------+--------------+--------------+
000 | [BX+SI] | [BX+SI+byte] | [BX+SI+word] |
001 | [BX+DI] | [BX+DI+byte] | [BX+DI+word] |
010 | [BP+SI] | [BP+SI+byte] | [BP+SI+word] |
011 | [BP+DI] | [BP+DI+byte] | [BP+DI+word] |
100 | [SI]   | [SI+byte]   | [SI+word]   |
101 | [DI]   | [DI+byte]   | [DI+word]   |
110 | [word] | [BP+byte]   | [BP+word]   |
111 | [BX]   | [BX+byte]   | [BX+word]   |
----+---------+--------------+--------------+
Hierbei bedeutet "+byte" (-128 .. +127) und "+word" (-32768..+32767).
Du kannst Parameter also nicht über [SP+4] adressieren.

Zur Begriffsklärung: der Stackframe ist der Bereich des Stacks, der von einer Prozedur benutzt wird. Dabei liegt irgendwo auf dem Stack ja die Rücksprungadresse zur aufrufenden Prozedur. Oberhalb dessen liegen die Parameter, die diese Prozedur für uns auf den Stack gepusht hat. Unterhalb dessen liegen die lokalen Variablen unserer Prozedur.

Beispiel:
Sagen wir mal, SP ist bei 1234 (hex). Jetzt wird unsere Prozedur aufgerufen mit "Proc(1, 4, 7)". In Assembler ist das:
Code:
push 1
push 4
push 7
call Proc
Der Stack sieht dann wie folgt aus:
Code:
1232 | 0001 <- 1. Parameter
1230 | 0004 <- 2. Parameter
122E | 0007 <- 3. Parameter
122C | 8341 <- Rücksprungadresse <- SP
Jetzt können wir unsere Parameter nicht mit [SP+2] oder [SP+4] adressieren, da es einen solchen Adressierungsmodus nicht gibt. Darum benutzt man BP als Zeiger auf den Stackframe. Wir führen aus:
Code:
push bp
mov bp, sp
und der Stack hat:
Code:
1232 | 0001 <- 1. Parameter
1230 | 0004 <- 2. Parameter
122E | 0007 <- 3. Parameter
122C | 8341 <- Rücksprungadresse
122A | 124A <- alter BP <- [b]SP[/b] <- [b]BP[/b]
Jetzt haben wir über [BP+8], [BP+6] und [BP+4] Zugriff auf die Parameter. Wenn wir lokale Variablen brauchen, dann belegen wir auch dafür Platz auf dem Stack, und zwar am unteren Ende des Stackframes:
Code:
sub sp, 8 ; 4 WORD
...und der Stack ist 8 Bytes nach unten gerutsch:
Code:
1232 | 0001 <- 1. Parameter
1230 | 0004 <- 2. Parameter
122E | 0007 <- 3. Parameter
122C | 8341 <- Rücksprungadresse
122A | 124A <- alter BP <- [b]BP[/b]
1228 | 7777 ; Zufallswerte
1226 | 5555
1224 | 3333
1222 | 8765 <- [b]SP[/b]
Diese Variablen können wir über [BP-2], [BP-4], [BP-6] und [BP-8] adressieren.

Jetzt können wir munter lustig vor uns hin programmieren, andere Prozeduren aufrufen usw. Am Ende räumen wir einfach den Stack wieder auf und springen zurück:
Code:
mov sp, bp ; löscht alle lokalen Variablen
pop bp     ; stellt BP wieder her
ret 6       ; springt zurück und löscht die Parameter vom Stack
Ich hoffe, das war jetzt etwas deutlicher. Wenn du einen Debugger hast, dann steppe so ein Programm mal in Einzelschritten durch.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat