2016-06-21 5 views
1

Мой вопрос касается RET Урны инструкции в 64-битный режим и их размер операнда, который определяет, сколько информации выставляется из стека в RIP и сколько байтов увеличивается на RSP.Какой размер операнда должен установить значение RET?

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

1   ; Assembled with NASM 2.12 command "nasm TestRET.asm -l TestRET.lst" 
2      BITS 64 
3 00000000 66CF  IRETW ; Opsize 16. 
4 00000002 CF   IRETD ; Opsize 32. 
5 00000003 48CF  IRETQ ; Opsize 64. 
6 00000005 66CF o16 IRET ; Opsize 16. 
7 00000007 CF  o32 IRET ; Opsize 32. 
8 00000008 48CF o64 IRET ; Opsize 64. 
9 0000000A CF   IRET ; Opsize 32, default. 
10     
11 0000000B 66CB o16 RETF ; Opsize 16. 
12 0000000D CB  o32 RETF ; Opsize 32. 
13 0000000E 48CB o64 RETF ; Opsize 64. 
14 00000010 CB   RETF ; Opsize 32, default. 
15     
16 00000011 66C3 o16 RETN ; Opsize 16. 
17 00000013 C3  o32 RETN ; Opsize 32 should not be available, NASM error? 
18 00000014 48C3 o64 RETN ; Opsize 64, REX.W ignored as RETN is promoted to 64 bits. 
19 00000016 C3   RETN ; Opsize 64, default. 

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

Какие операционные размеры программисты ожидают от ассемблера в 64-битном режиме, когда они используют IRET, RETF, RETN без дополнительной спецификации?

+0

Кто знает? Я сомневаюсь, что кто-то сделал опрос. Каков ваш реальный вопрос? –

+0

@RossRidge Должна ли моя программа переводить RETF как CB или 48CB? – vitsoft

+0

Ваша программа является ассемблером? Я не думаю, что это будет иметь большое значение, действительно нет никакой причины кодировать отдаленный доход в 64-битном коде. Также RETF официально не является инструкцией, поэтому, если вы ее задокументируете, вы можете делать все, что захотите. –

ответ

1

Предполагается, что запись ret в исходном файле asm будет собрана в однобайтную инструкцию.

IDK, почему кто-то будет использовать retf в 64-битном коде, поэтому у меня нет на это мнения.


При более внимательном ознакомлении с таблицей, я вижу, что вы говорите об переопределении операнда NASM. Это не специальный вариант o32/o64 модификаторов для таких инструкций, как RETN, что приводит к фиктивным поведенческим действиям, например o64 retn с префиксом REX.W = 1 (48 C3).

Я думаю, что мы должны понимать префикс o32 NASM как «префикс размера операнда в 16-битном коде, в противном случае ничего», независимо от того, к какой инструкции он применяется, и никогда не подразумевает REX.W = 0 (потому что это не работа в любом случае для push/pop).

И аналогично, o64 действительно означает, что применяется REX.W = 1, независимо от того, какая инструкция включена. то есть он не будет опускать его на insn, например push или pop, не так ли?



МСА разработан таким образом, что однобайтная ret инструкции "работа". Вам не нужен префикс REX для обычного ret. Как указано в the instruction set manual's ret entry:

В 64-битном режиме, размер операции по умолчанию этой инструкции является размер стека-адрес, то есть 64 бита. Это относится к близким доходам, не очень отдаленным; размер операции по умолчанию для далеких дат - 32 бита.

Это аналогично тому, как push/pop по умолчанию для 64-битных операндов размера в длительном режиме. (И, вопреки указаниям в руководстве, REX.W=0 не может кодировать 32-битный push/pop).

AMD обычно старалась упростить декодирование. например movsxd r64, r/m32 требует префикса REX (иначе он просто работает как потенциально менее эффективный mov), но для очень распространенных инструкций, таких как push/pop и ret, они сохраняют размер кода с такими вариантами дизайна.

+2

Сценарии для a16 retf и a32 retf - вы пытаетесь вернуться к 16 или 32-битовому коду. a64 retf, это сложно, но гипотетически, если вы только что перезагрузили GDT с помощью LGDT, а дескрипторы сегмента кода в таблицах были не такими, вам нужно заставить CS перезагрузить. В этом случае a64 retf будет иметь смысл. –

+1

@MichaelPetch Tnx, еще одним примером, требующим «o64 IRET (48CF)», может быть возврат от обработчика прерываний, вызванный кодом, загруженным выше 4 ГБ. BTW не должен читать 'o64, o32, o16', а не' a64, a32, a16'? AFAIK a64 (префикс размера адреса 67) не имеет смысла в инструкциях на основе RSP в режиме 64 бит, как описано в POP. Размер указателя стека фиксирован на 64 бита. – vitsoft

+0

Да @vitsoft все должно было быть 'o' not' a'. Был последний комментарий, который я сделал вчера вечером, и даже не заметил опечатки. –