сборка - вызовите printf с 64-битным содержимым памяти - PullRequest
0 голосов
/ 26 апреля 2020

Я хочу добавить число 0xFFFFFFFF к себе, а затем вывести результат на экран. Для этого я использую область памяти result для хранения результатов (может быть до 64 бит). Чтобы вызвать printf, мне нужно положить sh в стек, но это: push qword [result] не скомпилировано. есть ли способ отправить 64-битное число на printf?

section .data
fmt1: dq "%x", 10, 0
result: dd 0,0

section .text
    extern printf  

assFunc:

mov edx,0
mov eax, 0xFFFFFFFF
add eax, 0xFFFFFFFF
adc edx,0


mov [result],edx
mov [result+4],eax

push [result]
push fmt1
call printf
add esp,8 

1 Ответ

3 голосов
/ 26 апреля 2020

В вашем коде есть несколько ошибок.

Строка fmt определена с dq, который определяет группы QWORD (64-битные элементы). Это имеет эффект заполнения (с нулевыми байтами) каждой строки, кратной 8 байтам.
В этом случае вы потеряете символ новой строки.
Вместо этого используйте db.

Это также лучше следовать соглашению с прямым порядком байтов и хранить старшую часть числа в старших адресах.
edx - старшая часть результата, сохранять ее в [result + 4] и хранить eax (нижняя часть ) в [result].
Это позволяет другим программистам рассуждать о вашем коде. При той же длине вы также можете использовать xor edx, edx для установки edx на ноль .

Наконец, печатная часть.
Прежде всего, правильная строка формата %llx, поскольку модель, используемая основными компиляторами в 32-битном режиме, - LL64 (т. Е. long по-прежнему 32 бита, а long long - 64 бита).

ABI говорит, что вы должны передать long long аргументов в стеке и их выравнивание составляет 4 байта (что означает, что не нужно добавлять какие-либо отступы).
Кроме того, ABI требует , что стек должен быть выровнен по 16-байтовой границе непосредственно перед инструкцией call, но, к счастью, использование трех нажатий - это то, что необходимо для его выравнивания в любом случае. Поскольку x86 - это машины с прямым порядком байтов, это можно сделать с помощью:

push DWORD [result+4]
push DWORD [result]
push fmt1
call printf
add esp, 10h

Весь код:

SECTION .data

  fmt1:   db "%llx", 10, 0
  result: dd 0, 0


SECTION .text

    EXTERN printf  

assFunc:

  mov edx,0
  mov eax, 0xFFFFFFFF
  add eax, 0xFFFFFFFF
  adc edx,0

  mov [result],eax
  mov [result+4],edx

  push DWORD [result+4]
  push DWORD [result]
  push fmt1
  call printf
  add esp, 0ch 

  ret

Обратите внимание, что вам на самом деле не нужно сохранять результат в result переменная, вы можете

push edx
push eax

напрямую, вместо

push DWORD [result+4]
push DWORD [result]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...