Учебники

Сборка — Переменные

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

Выделение дискового пространства для инициализированных данных

Синтаксис для оператора распределения памяти для инициализированных данных:

[variable-name]    define-directive    initial-value   [,initial-value]...

Где имя переменной — это идентификатор для каждого пространства хранения. Ассемблер связывает значение смещения для каждого имени переменной, определенного в сегменте данных.

Существует пять основных форм директивы определения:

директива Цель Место для хранения
база данных Определить байт выделяет 1 байт
DW Определить слово выделяет 2 байта
DD Определить двойное слово выделяет 4 байта
DQ Определить Quadword выделяет 8 байтов
DT Определить десять байтов выделяет 10 байтов

Ниже приведены некоторые примеры использования директив define.

choice		DB	'y'
number		DW	12345
neg_number	DW	-12345
big_number	DQ	123456789
real_number1	DD	1.234
real_number2	DQ	123.456

Пожалуйста, обратите внимание, что —

  • Каждый байт символа хранится как его значение ASCII в шестнадцатеричном формате.

  • Каждое десятичное значение автоматически преобразуется в его 16-разрядный двоичный эквивалент и сохраняется в виде шестнадцатеричного числа.

  • Процессор использует байтовый порядок байтов.

  • Отрицательные числа преобразуются в его представление дополнения 2.

  • Короткие и длинные числа с плавающей запятой представлены с использованием 32 или 64 бит соответственно.

Каждый байт символа хранится как его значение ASCII в шестнадцатеричном формате.

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

Процессор использует байтовый порядок байтов.

Отрицательные числа преобразуются в его представление дополнения 2.

Короткие и длинные числа с плавающей запятой представлены с использованием 32 или 64 бит соответственно.

Следующая программа показывает использование директивы define —

Live Demo

section .text
   global _start          ;must be declared for linker (gcc)
	
_start:                   ;tell linker entry point
   mov	edx,1		  ;message length
   mov	ecx,choice        ;message to write
   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

section .data
choice DB 'y'

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

y

Выделение дискового пространства для неинициализированных данных

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

Существует пять основных форм директивы о запасах —

директива Цель
RESB Зарезервировать байт
RESW Зарезервировать слово
RESD Зарезервировать двойное слово
RESQ Зарезервировать Quadword
ОСТАЛЬНОЕ Зарезервировать десять байт

Несколько определений

Вы можете иметь несколько операторов определения данных в программе. Например —

choice	  DB 	'Y' 		 ;ASCII of y = 79H
number1	  DW 	12345 	 ;12345D = 3039H
number2    DD  12345679  ;123456789D = 75BCD15H

Ассемблер выделяет непрерывную память для нескольких определений переменных.

Несколько инициализаций

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

marks  TIMES  9  DW  0

Директива TIMES полезна при определении массивов и таблиц. Следующая программа отображает 9 звездочек на экране —

Live Demo

section	.text
   global _start        ;must be declared for linker (ld)
	
_start:                 ;tell linker entry point
   mov	edx,9		;message length
   mov	ecx, stars	;message to write
   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

section	.data
stars   times 9 db '*'

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