組み立て-手順

アセンブリ言語プログラムはサイズが大きくなる傾向があるため、プロシージャまたはサブルーチンはアセンブリ言語では非常に重要です。手順は名前で識別されます。この名前に続いて、明確に定義されたジョブを実行するプロシージャの本体が説明されています。プロシージャの終了は、returnステートメントによって示されます。

構文

以下は、プロシージャを定義するための構文です-

proc_name:
   procedure body
   ...
   ret

このプロシージャは、CALL命令を使用して別の関数から呼び出されます。CALL命令には、以下に示すように、呼び出されたプロシージャの名前を引数として指定する必要があります。

CALL proc_name

呼び出されたプロシージャは、RET命令を使用して、制御を呼び出し元のプロシージャに戻します。

ECXおよびEDXレジスタに格納されている変数を加算し、EAXレジスタに合計を返すsumという名前の非常に単純なプロシージャを記述してみましょう。

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

上記のコードをコンパイルして実行すると、次の結果が得られます。

The sum is:
9

スタックデータ構造

スタックは、メモリ内の配列のようなデータ構造であり、スタックの「トップ」と呼ばれる場所からデータを格納および削除できます。保存する必要のあるデータはスタックに「プッシュ」され、取得されるデータはスタックから「ポップ」されます。スタックはLIFOデータ構造です。つまり、最初に格納されたデータが最後に取得されます。

アセンブリ言語は、スタック操作にPUSHとPOPの2つの命令を提供します。これらの命令には、次のような構文があります。

PUSH    operand
POP     address/register

スタックセグメントに予約されているメモリスペースは、スタックの実装に使用されます。レジスタSSおよびESP(またはSP)は、スタックの実装に使用されます。スタックに挿入された最後のデータ項目を指すスタックの最上位は、SS:ESPレジスタによって示されます。ここで、SSレジスタはスタックセグメントの先頭を指し、SP(またはESP)はにオフセットを与えます。スタックセグメント。

スタックの実装には次の特徴があります-

  • のみ words または doublewords バイトではなく、スタックに保存できます。

  • スタックは逆方向、つまりメモリアドレスの低い方に向かって大きくなります。

  • スタックの最上位は、スタックに挿入された最後のアイテムを指します。最後に挿入されたワードの下位バイトを指します。

レジスタの値をスタックに格納してから使用することについて説明したように、それは次の方法で行うことができます-

; 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

次のプログラムは、ASCII文字セット全体を表示します。メインプログラムは、ASCII文字セットを表示するdisplayという名前のプロシージャを呼び出します。

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'

上記のコードをコンパイルして実行すると、次の結果が得られます。

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