Использование 32-разрядных инструкций push/pop в режиме x64

В 64-х битах занести в стек 32-биный регистр нельзя. Разве что разбить его на два 16-битных и их запушить.

Какой в этом смысл? Вы хотите сохранить младшую половину и потом восстановить её, не трогая старшую? Так не получится, потому как при записи в младшую часть старшая всегда обнуляется (с

pop

было бы так же).

Прыжок по 32-битному адресу из регистра (

jmp eax

) тоже сделать нельзя, но можно сделать так:

jmp dword [rax]

(и даже

jmp dword [eax]

). Или относительный прыжок: (

jmp $+0x1000000

).

Добавлено через 1 минуту

Нет 16-битных адресов в 64-битном режиме. А 32-битные есть:

AssemblerВыделить код

1
2
3
4

mov eax,[eax]
mov rax,[eax]
mov eax,[rax]
mov rax,[rax]

Добавлено через 6 минут

REX-префиксы

40h..4Fh

используется для перехода от 32 к 64-битным регистрам-операндам.

Префикс размера регистра

66h

используется для перехода от 32 к 16-битным регистрам-операндам.

Префикс размера адреса

67h

используется для перехода от 64 к 32-битой адресации.

Т.е. по умолчанию (без префиксов) используются 32-битные регистры-операнды и 64-битная адресация (в т.ч. 64-битные регистры в адресации), т.е. из приведённого выше примера

mov eax,[rax]

имеет самую короткую запись, а

mov rax,[eax]

– самую длинную.

Но к сожалению, операции

jmp/call

и

push/pop

с 32-битными регистрами-операндами невозможны, там используются 64-битные регистры по умолчанию и никакими префиксами это изменить нельзя.

С 16-битными регистрами (с префиксом

66h

) можно сделать

push/pop

, но не

jmp/call

– тут префикс просто не сработает.