Я немного ржавый на своем MASM, поэтому я действительно не помню, что делать здесь (если что-то вообще нужно делать). У меня есть процедура MASM (X86), которая выглядит следующим образом. Он имеет две локальные переменные, принимая до 5 байт Общее:Пролог «add esp, 0FFFFFFF8h»
MSC_ASM_GenerateBlock PROC buffer:DWORD,bsize:DWORD,safety:DWORD
LOCAL val:DWORD, rc:BYTE ;; local variables
MWSIZE EQU 4 ;; machine word size
.WHILE bsize >= MWSIZE && safety > 0
;; RDRAND is not available prior to VS2012. Just emit
;; the byte codes using DB. This is `rdrand eax`.
DB 0Fh, 0C7h, 0F0h
setc rc
...
.ENDW
...
MSC_ASM_GenerateBlock ENDP
Когда я проверяю разборку, я вижу:
> dumpbin.exe /DISASM rdrand-x86.obj
Dump of file rdrand-x86.obj
_MSC_ASM_GenerateBlock:
00000000: 55 push ebp
00000001: 8B EC mov ebp,esp
00000003: 83 C4 F8 add esp,0FFFFFFF8h
00000006: EB 1D jmp 00000025
00000008: 0F C7 F0 rdrand eax
0000000B: 0F 92 45 FB setb byte ptr [ebp-5]
0000000F: 80 7D FB 00 cmp byte ptr [ebp-5],0
...
я считаю add esp, 0FFFFFFF8h
это еще один способ сказать sub esp, 08h
.
Как указал Джошуа, разница между add esp
и sub esp
- это флаги после операции. Смущение ассемблера или выбор инструкций могут быть основаны на том факте, что ассемблер не видит контекст RDRAND
. Скорее, он видит только jmp
на основе CY
, и ассемблер считает, что флаги не в хорошем состоянии.
Почему MASM генерирует неинтуитивный add
, который зависит от целых целых чисел без знака? И что еще более важно, все в порядке?
Я выполнил порт маршрутизации на MASM64/ML64, используя более широкие машинные слова. Он производит тот же код (размер по модулю машинного слова):
Dump of file rdrand-x64.obj
MSC_ASM_GenerateBlock:
0000000000000000: 55 push rbp
0000000000000001: 48 8B EC mov rbp,rsp
0000000000000004: 48 83 C4 F0 add rsp,0FFFFFFFFFFFFFFF0h
0000000000000008: EB 1D jmp 0000000000000037
0000000000000010: 48 0F C7 F0 rdrand rax
000000000000001D: 0F 92 45 F7 setb byte ptr [rbp-9]
0000000000000024: 80 7D F7 00 cmp byte ptr [rbp-9],0
...
* "... кроме того, что он устанавливает бит бит по-разному" * - возможно, это все. Хотя 'RDRAND' устанавливает флаги, компилятор не может сказать, потому что он нацелен на' cl.exe' и 'ml.exe', поставляемые с VS2005, VS2008 и VS2010 (ни один из них не может испускать' RDRAND'). Все компилятор и ассемблер видят/понимают переход, основанный на 'CY', без контекста' RDRAND'. – jww
Но это не он. Вы не проверяете бит флага после изменения esp. – Joshua
Хороший вопрос ... Но, как вы сказали, странно ... Его почему это вызвало мой интерес. – jww