Обратите внимание, что, как прокомментировано, MASM игнорирует []. Вместо этого MASM идет по типу метки. В этом случае проблема заключается в том, что: after table (table :) создает метку типа «код», которая обычно используется в качестве цели перехода или вызова, поэтому jmp [таблица] или таблица jmp переходят в таблицу так, как если бы она былаcode.
Удаление: и помещение qword (или dq можно использовать) в одну строку, изменение таблицы на тип qword, поэтому jmp [table] или jmp table загружает адрес qword из таблицы в RIPи выполняет ветвление как требуется.
table qword subroutine, subroutine2
Однако, если вы хотите проиндексировать таблицу, вам нужно будет либо использовать регистр для хранения смещения таблицы (например, lea r9, table),или в случае Visual Studio перейдите в проект / свойства / компоновщик / система / включить большие адреса: нет (устанавливает параметр компоновщика / LARGEADDRESSAWARE: NO). Ниже я разместил примеры для обоих случаев.
Этот пример работает с ML64.EXE (MASM) из Visual Studio. Таблица может быть в разделе кода или данных. Если таблица является первой строкой в данных, lea генерирует {4C 8D 0D 79 E5 00 00}, если таблица является первой строкой в коде, lea генерирует {4C 8D 0D E1 FF FF FF}. Я не знаю, что лучше для производительности. Казалось бы, если кэш данных используется не полностью, то он будет хранить копию таблицы кеша данных.
.data
tbl dq fun1, fun2, fun3 ;table
.code
main proc
lea r9,tbl
mov rax,0
main0: jmp qword ptr [r9+rax*8]
main1:: inc rax
cmp rax,3
jb main0
xor eax,eax
ret
main endp
fun1 proc
mov rdx,1
jmp main1
fun1 endp
fun2 proc
mov rdx,2
jmp main1
fun2 endp
fun3 proc
mov rdx,3
jmp main1
fun3 endp
end
С параметром компоновщика Visual Studio / LARGEADDRESSAWARE: НЕТ, тамнет необходимости использовать второй регистр. Таблица может быть в разделе данных или кода. Если таблица является первой строкой в данных, jmp генерирует {FF 24 C5 00 00 3D 00}, если таблица является первой строкой в коде, jmp генерирует {FF 24 C5 80 1A 2D 01}. Я не знаю, что лучше для производительности. Казалось бы, если кэш данных используется не полностью, то он будет хранить копию таблицы кеша данных.
.data
tbl dq fun1, fun2, fun3 ;table
.code
main proc
mov rax,0
main0: jmp qword ptr [tbl+rax*8]
main1:: inc rax
cmp rax,3
jb main0
xor eax,eax
ret
main endp
fun1 proc
mov rdx,1
jmp main1
fun1 endp
fun2 proc
mov rdx,2
jmp main1
fun2 endp
fun3 proc
mov rdx,3
jmp main1
fun3 endp