Указатели

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

Ассемблер позволяет определять указатели - переменные, которые хранят адрес других объектов. Для получения адреса объекта применяется выражение

offset переменная

Поскольку адрес в архитектуре x86-64 занимает 8 байт, то для хранения адреса нам надо определить переменную с типом qword. Например, определим переменную и получим ее адрес:

.data
    n dword 22
    pn qword ?
.code
main proc
    ; установка указателя
    mov rax, offset n       ; загружаем адрес переменной n
    mov pn, rax             ; сохраняем адрес в переменную pn

    ; получение данных по указателю
    mov rbx, pn             ; в rbx помещаем адрес из переменной pn
    mov rax, [rbx]          ; обращаемся по адресу из rbx
    ret
main endp
end

Здесь определена переменная-указатель pn, которая представляет тип qword и которая будет хранить адрес переменной n. Сначала получаем адрес в регистр RAX и затем передаем его в указатель pn:

mov rax, offset n
mov pn, rax

Если нам надо использовать значение по указателю, можно сначала поместить значение указателя в регистр, а затем использовать косвенную адресацию для получения самого значения по указателю.

mov rbx, pn             ; в rbx помещаем адрес из переменной p
mov rax, [rbx]          ; обращаемся по адресу из rbx

В итоге в регистре RAX окажется число 22 - значение переменной n.

При этом мы можем получить адрес уже при определении переменной-указателя:

.data
    n dword 11
    pn qword offset n   ; получаем адрес переменной n
.code
main proc
    ; получение данных по указателю
    mov rbx, pn              ; в rbx помещаем адрес из переменной pn
    mov rax, [rbx]          ; в RAX число 11
    ret
main endp
end

Указатель необязательно должен представлять переменную - это может быть и константа:

pn equ offset n     ; константа pn указывает на переменную n
.data
    n dword 12
.code
main proc
    ; получение данных по указателю
    mov rbx, pn              ; в rbx помещаем адрес из переменной pn
    mov rax, [rbx]          ; в RAX число 11
    ret
main endp
end

Операции с адресом

При получении адреса мы можем использовать ряд операций:

offset переменная [смещение]
offset переменная + смещение
offset переменная - смещение

В этом случае мы можем получить адрес, который смещен относительно адреса переменной на несколько байтов вперед или назад. Выражение переменная [смещение] фактически эквивалентно выражению переменная + смещение. Например:

.data
    nums dword 11, 12, 13, 14, 15, 16
    p qword ?
.code
main proc
    ; установка указателя
    mov rax, offset nums + 4    ; загружаем адрес переменной nums + 4
    mov p, rax                  ; сохраняем адрес в переменную p

    ; получение данных по указателю
    mov rbx, p              ; в rbx помещаем адрес из переменной p
    mov rax, [rbx]          ; обращаемся по адресу из rbx
    ret
main endp
end

Здесь переменная nums представляет набор 32-битных чисел. Выражение offset nums возвращает адрес перемнной num - адрес первого числа из этого набора. Соответственно чтобы получить адрес второго числа из этого набора, нам надо прибавить размер одного элемента в байтах, то есть 4 байта - offset nums + 4

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