Как перевести “pushl 2000” из AT & T asm в синтаксис Intel на i386
Вопрос
Я пытаюсь перевести следующее с AT & T assembly на Intel assembly:
pushl 2000
Теперь это компилируется до:
ff 35 d0 07 00 00 pushl 0x7d0
Но независимо от того, что я пытаюсь, я не могу получить то же самое в Intel synax, я пробовал:
intel asm
disassembly after compiling to at&t
push 2000
68 d0 07 00 00 push $0x7d0
push [2000]
68 d0 07 00 00 push $0x7d0
push dword ptr [2000]
68 d0 07 00 00 push $0x7d0
push dword ptr 2000
68 d0 07 00 00 push $0x7d0
Итак, у меня закончились подсказки, что такое эквивалент "pushl 2000"?
Решение
Я думаю, что исходный код делает не то, что вы думаете, что он делает.Согласно msdev, разборка является:
003AFCFC FF 35 D0 07 00 00 push dword ptr ds:[7D0h]
Что равносильно толчку:
*((DWORD*)2000)
НЕ помещая значение 2000 в стек.Однако - если это действительно то, чего вы хотите, то инструкция такова:
push dword ptr ds:[2000]
ds:
является указанием на использование ds
сегментный регистр.Сегментные регистры - это пережиток неприятных 16-битных времен.Основными из них являются cs
- сегмент кода, ds
- сегмент данных и ss
- сегмент стека (и fs
именно там хранятся локальные потоки).Думайте о них как о базовых смещениях в память.По умолчанию доступ к данным отключен ds
сегмент.
Мое предположение относительно того, почему push dword ptr [2000]
не сработало то, что компилятор понял, что это было глупо с вашей стороны использовать, и "исправил это".Путем принудительного использования ds
префикс, которым вы указываете, что вы действительно хотите выполнить там доступ к памяти.
Другие советы
для меня, в GNU assembler 2.18, для 32-разрядной целевой
.intel_syntax
push dword [2000]
генерирует :
0: ff 35 d0 07 00 00 pushl 0x7d0
и для nasm :
push dword [dword 2000]