x64調(diào)用規(guī)范第3行調(diào)用者的責(zé)任,還包括在運(yùn)行時(shí)堆棧分配至少32字節(jié)的影子空間,這樣被調(diào)用的過(guò)程就可以選擇將計(jì)算器參數(shù)保存在這個(gè)區(qū)域中。問(wèn)題這里的影子空間32字節(jié),我咋沒(méi)看出來(lái)是啥意思以及它們的作用。 %20%20%20
我自己答吧 終于明白了、、預(yù)留32字節(jié)的影子空間 其實(shí)是在調(diào)用系統(tǒng)外部鏈接庫(kù)和 和 其他外部庫(kù)時(shí) 用的 而一般自定義的調(diào)用過(guò)程 不用如此。因?yàn)?在自定義的過(guò)程里其實(shí)是沒(méi)必要的 因?yàn)?可以在過(guò)程里直接 PUSH XXX然后結(jié)束時(shí)在POPXXX 堆棧就復(fù)原了(在過(guò)程運(yùn)行完時(shí)一般必須如此)例如we procpush raxpush rbx.... ....pop rbxpop raxretwe endp
而調(diào)用外部鏈接庫(kù)過(guò)程時(shí)。因?yàn)闊o(wú)法改動(dòng)外部庫(kù)的過(guò)程中的內(nèi)容。所以在調(diào)用庫(kù)過(guò)程之前無(wú)法保證PUSH 使用之后調(diào)用外部庫(kù)過(guò)程返回后 PUSH指令的 堆棧順序還能對(duì)上之前的 PUSH和POP成對(duì)使用。 因?yàn)闊o(wú)法保證在外部過(guò)程中PUSH和POP的成對(duì)使用。。而臨時(shí)保存寄存器內(nèi)容在不適用全局變量的情況下 對(duì)RSP指針的所在堆棧內(nèi)存地址進(jìn)行手動(dòng)地址下移 預(yù)留出空間 然后使用 直接尋址方式 來(lái)訪(fǎng)問(wèn)預(yù)留的堆??臻g是最好的且不出意外的方式而且 調(diào)用外部過(guò)程是有規(guī)范的。。(只使用4個(gè)寄存器往外部庫(kù)過(guò)程傳遞參數(shù)更多的使用堆棧而堆棧等下可以手動(dòng)恢復(fù)指針地址廢掉數(shù)據(jù)還原RSP地址到之前的正確位置)所以只需要使用4個(gè)64位寄存器 4乘以8字節(jié)等于32字節(jié)。。所以預(yù)留32字節(jié)的影子空間使用直接尋址方式訪(fǎng)問(wèn) 在恢復(fù) 4個(gè)傳遞參數(shù)的寄存器之后 就可以手動(dòng) 使用命令 ADD rsp ,xxx 之類(lèi)的命令 恢復(fù)堆棧RSP指針 使其復(fù)原
其實(shí)就是主調(diào)程序 為被調(diào)用程序預(yù)留的 4個(gè) 64位存儲(chǔ)空間 可通過(guò)_直接尋址方式**_訪(fǎng)問(wèn)。。這是WINDOWSAPI 64 的規(guī)范。具體用不用如何使用是 WINDOWS API 的事情(外部調(diào)用過(guò)程 無(wú)法自己修改)一般來(lái)說(shuō)是用來(lái)暫存 傳遞參數(shù)的寄存器的值得 騰出來(lái)寄存器 以便 外部庫(kù)過(guò)程使用。且外部庫(kù)過(guò)程使用堆棧結(jié)束后需清除所有參數(shù)使用的堆棧空間和影子空間 需把堆棧指針復(fù)原到RSP指針未因?yàn)橥獠繋?kù)過(guò)程而被修改之前的地址。