Получение текущего адреса

Последнее обновление: 14.10.2023

Для получения текущего адреса в ассемблере NASM применяется оператор точка $. Например:

currentAddr dq $

Здесь переменная currentAddr хранит свой собственный адрес.

Мы можем манипулировать подобной переменной также, как и другими переменными. Например, получим значение, которое идет до этой переменной на примере программы на Linux:

global _start

section .data
nums dq 112, 113, 114, 115, 116  ; массив чисел qword
currentAddr dq $

section .text
_start:
    mov rdi, [currentAddr - 8]  ; rdi = 116
    mov rax, 60
    syscall 

Выражение [currentAddr - 8] обращается к значению, которое идет на 8 байт назад от расположение переменной currentAddr, а это последний элемент массива nums - число 116.

Получение текущего адреса может помочь в ряде задач. Распространенная задача - получение длины строки или массива чисел. В общем случае мы можем определить переменную и непосредственно присвоить ей размер. Однако при этом можно ошибиться, неправильно подсчитать. Использование текущего адреса позволяет решить эту задачу:

global _start

section .data
nums dq 112, 113, 114, 115, 116  ; массив чисел qword
numsLength equ $ - nums     ; хранит размер массива nums

section .text
_start:
    mov rdi, numsLength  ; rdi = 40
    mov rax, 60
    syscall 

Здесь выражение $ - nums отнимает от текущего адреса адрес переменной nums, и таким образом константа numsLength фактически представляет размер массива nums. То есть в регистрре RDI будет помещаться число 40 (5 чисел по 8 байт). Поскольку размер массива - величина не изменяемая, то в данном случае длина массива определена как константа, а не переменная

Однако нам бы хотелось найти количество элементов в массиве, а не просто его длину. В этом случае можно разделить полученное значение на размер элемента (пример на Linux):

global _start

section .data
nums dq 112, 113, 114, 115, 116  ; массив чисел qword
numsCount equ ($ - nums) / 8     ; хранит количество элементов массива nums

section .text
_start:
    mov rdi, numsCount  ; rdi = 5
    mov rax, 60
    syscall 

Поскольку мы имеет дело с 8-байтными числами, то размер массива делим на 8 и таким образом получаем количество элементов.

numsCount equ ($ - nums) / 8

Аналогичный пример на Windows:

global _start

section .data
nums dq 112, 113, 114, 115, 116  ; массив чисел qword
numsCount equ ($ - nums) / 8     ; хранит количество элементов массива nums

section .text
_start:
    mov rax, numsCount  ; rax = 5
    ret    

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850