Montage - Verfahren

Prozeduren oder Unterprogramme sind in der Assemblersprache sehr wichtig, da die Assemblersprachenprogramme in der Regel groß sind. Prozeduren sind durch einen Namen gekennzeichnet. Nach diesem Namen wird der Hauptteil der Prozedur beschrieben, die eine genau definierte Aufgabe ausführt. Das Ende des Vorgangs wird durch eine return-Anweisung angezeigt.

Syntax

Es folgt die Syntax zum Definieren einer Prozedur:

proc_name:
   procedure body
   ...
   ret

Die Prozedur wird von einer anderen Funktion mit der Anweisung CALL aufgerufen. Die CALL-Anweisung sollte den Namen der aufgerufenen Prozedur als Argument haben, wie unten gezeigt -

CALL proc_name

Die aufgerufene Prozedur gibt die Steuerung unter Verwendung der RET-Anweisung an die aufrufende Prozedur zurück.

Beispiel

Schreiben wir eine sehr einfache Prozedur namens sum , die die im ECX- und EDX-Register gespeicherten Variablen addiert und die Summe im EAX-Register zurückgibt.

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   mov	ecx,'4'
   sub     ecx, '0'
	
   mov 	edx, '5'
   sub     edx, '0'
	
   call    sum          ;call sum procedure
   mov 	[res], eax
   mov	ecx, msg	
   mov	edx, len
   mov	ebx,1	        ;file descriptor (stdout)
   mov	eax,4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	ecx, res
   mov	edx, 1
   mov	ebx, 1	        ;file descriptor (stdout)
   mov	eax, 4	        ;system call number (sys_write)
   int	0x80	        ;call kernel
	
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
sum:
   mov     eax, ecx
   add     eax, edx
   add     eax, '0'
   ret
	
section .data
msg db "The sum is:", 0xA,0xD 
len equ $- msg   

segment .bss
res resb 1

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

The sum is:
9

Stapelt Datenstruktur

Ein Stapel ist eine Array-ähnliche Datenstruktur im Speicher, in der Daten gespeichert und von einem Ort entfernt werden können, der als "Oberseite" des Stapels bezeichnet wird. Die Daten, die gespeichert werden müssen, werden in den Stapel "geschoben" und die abzurufenden Daten werden aus dem Stapel "herausgeschleudert". Der Stapel ist eine LIFO-Datenstruktur, dh die zuerst gespeicherten Daten werden zuletzt abgerufen.

Die Assemblersprache enthält zwei Anweisungen für Stapeloperationen: PUSH und POP. Diese Anweisungen haben Syntaxen wie -

PUSH    operand
POP     address/register

Der im Stapelsegment reservierte Speicherplatz wird zum Implementieren des Stapels verwendet. Die Register SS und ESP (oder SP) werden zur Implementierung des Stapels verwendet. Auf die Oberseite des Stapels, die auf das letzte in den Stapel eingefügte Datenelement zeigt, zeigt das SS: ESP-Register, wobei das SS-Register auf den Anfang des Stapelsegments zeigt und der SP (oder ESP) den Versatz in angibt das Stapelsegment.

Die Stapelimplementierung weist die folgenden Merkmale auf:

  • Nur words oder doublewords könnte im Stapel gespeichert werden, kein Byte.

  • Der Stapel wächst in umgekehrter Richtung, dh in Richtung der unteren Speicheradresse

  • Die Oberseite des Stapels zeigt auf das zuletzt in den Stapel eingefügte Element. es zeigt auf das untere Byte des zuletzt eingefügten Wortes.

Wie wir über das Speichern der Werte der Register im Stapel besprochen haben, bevor sie für eine bestimmte Verwendung verwendet wurden; es kann folgendermaßen geschehen:

; Save the AX and BX registers in the stack
PUSH    AX
PUSH    BX

; Use the registers for other purpose
MOV	AX, VALUE1
MOV 	BX, VALUE2
...
MOV 	VALUE1, AX
MOV	VALUE2, BX

; Restore the original values
POP	BX
POP	AX

Beispiel

Das folgende Programm zeigt den gesamten ASCII-Zeichensatz an. Das Hauptprogramm ruft eine Prozedur namens display auf , die den ASCII-Zeichensatz anzeigt.

section	.text
   global _start        ;must be declared for using gcc
	
_start:	                ;tell linker entry point
   call    display
   mov	eax,1	        ;system call number (sys_exit)
   int	0x80	        ;call kernel
	
display:
   mov    ecx, 256
	
next:
   push    ecx
   mov     eax, 4
   mov     ebx, 1
   mov     ecx, achar
   mov     edx, 1
   int     80h
	
   pop     ecx	
   mov	dx, [achar]
   cmp	byte [achar], 0dh
   inc	byte [achar]
   loop    next
   ret
	
section .data
achar db '0'

Wenn der obige Code kompiliert und ausgeführt wird, ergibt sich das folgende Ergebnis:

0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}
...
...