Printf на masm x64 с несколькими параметрами - PullRequest
0 голосов
/ 27 сентября 2018

Мне нужно создать функцию в asm (в Windows), которая воспроизводит следующее поведение:

_int64 q(_int64 a, _int64 b, _int64 c, _int64 d, _int64 e) {
     _int64 sum = a + b + c + d + e;
      printf("a = %I64d b = %I64d c = %I64d d = %I64d e = %I64d sum = %I64d\n", a, b, c, d, e, sum);
      return sum;
}

Я знаю, что мне нужно выделить теневое пространство для printf, а также мне нужно сохранить некоторые параметры встек, потому что только первые 4 параметра находятся в регистрах (rcx, rdx, r8 и r9)

Моя проблема связана с форматом строки и управлением стеком.Пока мой код выглядит следующим образом:

.data   
string1 dq 'a = %I64d b = %I64d c = %I64d d = %I64d e = %I64d sum = %I64d', 10, 0       ; The printf format, "\n",'0'

.code
    public      q                               ;a in rcx, b in rdx, c in r8, d in r9, e in stack
    q:          push rbp
                mov rbp, rsp                    
                sub rsp, 32                     ;allocating shadow space for printf
                                                ;for calling printf, we need to have [string] in rcx, 
                                                ;a in rdx, b in r8, c in r9, d in stack1, e in stack2, and sum in stack3
                add rax, rcx                    ;first make the sum
                add rax, rdx                    
                add rax, r8
                add rax, r9
                mov rbx, [rbp + 8]              ;getting e from the stack
                add rax, rbx                    ;final add, in rax now is sum
                push rax                        ;changing parameters in registers (last 3 in stack)
                push rbx
                push r9
                mov r9, r8                      ;c in r9
                mov r8, rdx                     ;b in r8
                mov rdx, rcx                    ;a in rdx
                lea rcx, [string]               ;string in rcx
                call printf
                mov rsp, rbp                    ;back to previous pointer
                pop rbp                         ;release resources
                ret 0
    end

В данный момент он не компилируется с ошибкой

A2084: слишком большое значение константы

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

Пожалуйста, я был бы признателен за любую помощь.Спасибо!

1 Ответ

0 голосов
/ 27 сентября 2018

Если эта ошибка находится в строке со строкой, используйте db вместо dq: вы не хотите, чтобы элементы 10, 0 были дополнены до qwords, даже если он принял часть в кавычках как строкуNASM делает.

Я думаю, что MASM допускает кавычечные константы для db, поэтому он должен собрать его.


Но не ссылка: вам понадобится call _printf, потому что этокак Windows украшает имена C.

И затем у нас есть несколько других ошибок во время выполнения:

Кроме того, вам нужно sub rsp, 32, чтобы зарезервировать теневое пространство после нажатия 3 регистров, если вы хотите восстановить их после.В противном случае эти 24 байта являются нижней частью теневого пространства, которое видит вызываемая функция (printf).

Но это бессмысленно, потому что вы не восстанавливаете их после вызова.Таким образом, вы нарушаете соглашение о вызовах, забивая rbx;Похоже, что вы ничего не делаете с ними после вызова, так что просто используйте reg-clobbered reg или лучше сначала вычислите значение в правом регистре передачи аргументов.

...