1) push byte
в NASM 2.11 64-битная компиляция аналогична просто push
, за исключением того, что она отказывается компилироваться, если выдаваемая вещь больше байта:
push 0x0000
push 0x01
push 0x0001
push 0x10
Так же, как:
push byte 0x0000
push byte 0x01
push byte 0x0001
push byte 0x10
Но следующая ошибка:
push byte 0x0100
push byte 0x1000
push byte 0x01000000
push byte 0x10000000
Все они скомпилированы в форму инструкции 6a XX
.
2) NASM и GAS автоматически решают, какую форму использовать, исходя из размера операнда:
ГАЗ 2.25:
push $0x0000
push $0x01
push $0x0001
push $0x10
push $0x0100
push $0x1000
push $0x01000000
push $0x10000000
Компилируется так же, как NASM:
push 0x0000
push 0x01
push 0x0001
push 0x10
push 0x0100
push 0x1000
push 0x01000000
push 0x10000000
Objdump:
0: 6a 00 pushq $0x0
2: 6a 01 pushq $0x1
4: 6a 01 pushq $0x1
6: 6a 10 pushq $0x10
8: 68 00 01 00 00 pushq $0x100
d: 68 00 10 00 00 pushq $0x1000
12: 68 00 00 00 01 pushq $0x1000000
17: 68 00 00 00 10 pushq $0x10000000
Так что push
в GAS - это то же самое, что push byte
в NASM, но без проверки ошибок.
3) Модификатор, который существует существует в ГАЗЕ: w
как в:
pushw $0
, который компилируется в:
0: 66 6a 00 pushw $0x0
, т. Е. Добавляет префикс 0x66
для переключения 16-битной операции.
Эквивалент NASM:
push word 0
4) Отличие от mov
состоит в том, что мы не можем контролировать произвольные размеры push: все они представляют собой фиксированные фиксированные суммы в стеке.
Единственный параметр, который мы можем контролировать в кодировке инструкций, это включать префикс 0x66
или нет.
Остальное определяется дескриптором сегмента. См. Руководство разработчика программного обеспечения для архитектуры Intel 64 и IA-32 - Том 2: Справочник по набору инструкций - 325383-056US Сентябрь 2015 .