x64調用規(guī)范第3行調用者的責任,還包括在運行時堆棧分配至少32字節(jié)的影子空間,這樣被調用的過程就可以選擇將計算器參數保存在這個區(qū)域中。問題這里的影子空間32字節(jié),我咋沒看出來是啥意思以及它們的作用。 %20%20%20
我自己答吧 終于明白了、、預留32字節(jié)的影子空間 其實是在調用系統外部鏈接庫和 和 其他外部庫時 用的 而一般自定義的調用過程 不用如此。因為 在自定義的過程里其實是沒必要的 因為 可以在過程里直接 PUSH XXX然后結束時在POPXXX 堆棧就復原了(在過程運行完時一般必須如此)例如we procpush raxpush rbx.... ....pop rbxpop raxretwe endp
而調用外部鏈接庫過程時。因為無法改動外部庫的過程中的內容。所以在調用庫過程之前無法保證PUSH 使用之后調用外部庫過程返回后 PUSH指令的 堆棧順序還能對上之前的 PUSH和POP成對使用。 因為無法保證在外部過程中PUSH和POP的成對使用。。而臨時保存寄存器內容在不適用全局變量的情況下 對RSP指針的所在堆棧內存地址進行手動地址下移 預留出空間 然后使用 直接尋址方式 來訪問預留的堆??臻g是最好的且不出意外的方式而且 調用外部過程是有規(guī)范的。。(只使用4個寄存器往外部庫過程傳遞參數更多的使用堆棧而堆棧等下可以手動恢復指針地址廢掉數據還原RSP地址到之前的正確位置)所以只需要使用4個64位寄存器 4乘以8字節(jié)等于32字節(jié)。。所以預留32字節(jié)的影子空間使用直接尋址方式訪問 在恢復 4個傳遞參數的寄存器之后 就可以手動 使用命令 ADD rsp ,xxx 之類的命令 恢復堆棧RSP指針 使其復原
其實就是主調程序 為被調用程序預留的 4個 64位存儲空間 可通過_直接尋址方式**_訪問。。這是WINDOWSAPI 64 的規(guī)范。具體用不用如何使用是 WINDOWS API 的事情(外部調用過程 無法自己修改)一般來說是用來暫存 傳遞參數的寄存器的值得 騰出來寄存器 以便 外部庫過程使用。且外部庫過程使用堆棧結束后需清除所有參數使用的堆??臻g和影子空間 需把堆棧指針復原到RSP指針未因為外部庫過程而被修改之前的地址。
影子空間的作用是為了入棧的參數能順序一致,說簡單點,就是前4個是通過rcx,rdx,r8,r9傳遞,而后面的是用入棧的形式,也就是說沒有影子空間的化,獲取參數就是得從寄存器和棧這邊取,而有影子空間就不用,直接從棧中獲取即可,因為預留得32字節(jié)空間,是存放了數據副本,所以目前我猜測就是入棧的時候能與以前win32時候一樣,都是以棧傳遞,方便管理。其實它就是把那四個寄存器的值復制到棧中,然后順序搞好就是所有參數從右往左入棧一樣。八成是為了兼容win32用或者其他平臺,反正作用沒那么重要,重要是知道這貨怎么用就行。平衡棧,要怎么平衡