Учебники

Сборка — Макросы

Написание макроса — это еще один способ обеспечения модульного программирования на ассемблере.

  • Макрос — это последовательность инструкций, присваиваемая именем и может использоваться в любом месте программы.

  • В NASM макросы определяются с помощью директив % macro и % endmacro .

  • Макрос начинается с директивы% macro и заканчивается директивой% endmacro.

Макрос — это последовательность инструкций, присваиваемая именем и может использоваться в любом месте программы.

В NASM макросы определяются с помощью директив % macro и % endmacro .

Макрос начинается с директивы% macro и заканчивается директивой% endmacro.

Синтаксис для определения макроса —

%macro macro_name  number_of_params
<macro body>
%endmacro

Где number_of_params указывает параметры числа, а macro_name указывает имя макроса.

Макрос вызывается с использованием имени макроса вместе с необходимыми параметрами. Когда вам нужно многократно использовать некоторую последовательность инструкций в программе, вы можете поместить эти инструкции в макрос и использовать их вместо того, чтобы писать инструкции постоянно.

Например, очень распространенная потребность в программах заключается в написании строки символов на экране. Для отображения строки символов вам понадобится следующая последовательность инструкций —

mov	edx,len	    ;message length
mov	ecx,msg	    ;message to write
mov	ebx,1       ;file descriptor (stdout)
mov	eax,4       ;system call number (sys_write)
int	0x80        ;call kernel

В приведенном выше примере отображения строки символов регистры EAX, EBX, ECX и EDX были использованы вызовом функции INT 80H. Таким образом, каждый раз, когда вам нужно отобразить на экране, вам нужно сохранить эти регистры в стеке, вызвать INT 80H и затем восстановить исходное значение регистров из стека. Поэтому было бы полезно написать два макроса для сохранения и восстановления данных.

Мы заметили, что некоторые инструкции, такие как IMUL, IDIV, INT и т. Д., Нуждаются в том, чтобы некоторая информация была сохранена в некоторых конкретных регистрах и даже возвращала значения в некоторых конкретных регистрах. Если программа уже использовала эти регистры для хранения важных данных, то существующие данные из этих регистров должны быть сохранены в стеке и восстановлены после выполнения инструкции.

пример

В следующем примере показано определение и использование макросов —

Live Demo

; A macro with two parameters
; Implements the write system call
   %macro write_string 2 
      mov   eax, 4
      mov   ebx, 1
      mov   ecx, %1
      mov   edx, %2
      int   80h
   %endmacro
 
section	.text
   global _start            ;must be declared for using gcc
	
_start:                     ;tell linker entry point
   write_string msg1, len1               
   write_string msg2, len2    
   write_string msg3, len3  
	
   mov eax,1                ;system call number (sys_exit)
   int 0x80                 ;call kernel

section	.data
msg1 db	'Hello, programmers!',0xA,0xD 	
len1 equ $ - msg1			

msg2 db 'Welcome to the world of,', 0xA,0xD 
len2 equ $- msg2 

msg3 db 'Linux assembly programming! '
len3 equ $- msg3

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —