簡體   English   中英

具有多個參數的 masm x64 上的 Printf

[英]Printf on masm x64 with multiple parameters

我需要在 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,在這種情況下,我需要在堆棧中存儲一些其他參數,然后我不太確定如何進行...

如果該錯誤與字符串一致,請使用db而不是dq :您不希望將10, 0元素填充到 qwords 中,即使它確實像 NASM 那樣接受引用的部分作為字符串。

我認為 MASM 允許為db引用常量,因此應該可以組裝它。


然后我們在運行時還有多個其他錯誤:

另外,如果要推送3個寄存器后恢復它們,則需要sub rsp, 32以保留陰影空間。 否則,這 24 個字節是被調用函數 ( printf ) 看到的影子空間的底部。

但這毫無意義,因為您沒有在通話后恢復它們。 因此,您通過破壞rbx違反了調用約定; 看起來你在調用之后沒有對它們做任何事情,所以只需使用調用破壞的 reg,或者最好首先計算正確的 arg-passing 寄存器中的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM