免責聲明:內容僅供學習參考,請合法利用知識,禁止進行違法犯罪活動!
本次游戲沒法給
內容參考于:微塵網絡安全
上一個內容:34.x64匯編寫法(一)
上一個內容寫了,匯編調用c標準庫里的getchar函數,這次寫的是c調用匯編
首先說明一下 extern 這個單詞,只要有 extern 這個單詞就說明當前函數或變量是一個全局的,比如 extern int f; 這個代碼,現在在文件1中寫 extern int f; 然后文件2中也寫 extern int f; ,文件1中把f的值設置成了10,然后在文件2中什么都不寫,只寫extern int f;這一句,此時f的值會是10,因為是全局的,文件1中的修改影響到了它,函數也一樣(可能普通手段沒辦法修改函數,因為會語法不通過)
c代碼
#include <iostream>// 帶著 extern 這個單詞就說明從全局中找,帶著extern它的如果函數名重復了會出現問題
// 在全局中找一個 addShu ,這個addShu函數實用匯編實現的
extern "C" int addShu(int s1, int s2);
int main() {int num = addShu(11, 23);printf("num = %d", num);
}
匯編代碼,addShu函數的實現
.codeaddShu procsub rsp, 100h ; 開辟棧xor rax, raxmov rax, rcx ; 獲取第一個參數給raxadd rax, rdx ; 第一個參數與第二個參數進行相加add rsp, 100h ; 恢復棧ret ; 返回addShu endpend
效果圖:
然后有一個問題,把num改成從全局的,并把它的值設置成999
匯編代碼的修改,正常運行的話,它會返回999
實際上它返回的是 -1892892644
這里直接說答案-1892892644是num的內存地址,怎么發現通過斷點,如下圖設置斷點(鼠標左鍵單擊紅色圓的位置就可以設置斷點和取消斷點)
運行后斷點住
然后打開監視窗口
然后可以看到它們倆的值是正常的
然后點擊下圖紅框位置,運行一行代碼
然后看到rax的值并不是999
然后寫一個 &num 表示取num的內存地址
然后鼠標右擊選擇以十六進制顯示
然后就能發現rax的值是num的內存地址了
這個問題就是這里的mov變成了lea,所以要注意在使用全局變量賦值的時候,多寫一句 mov rax,[rax]這樣的代碼,如下圖紅框
效果圖:
匯編代碼
extern num:far
.codeaddShu procsub rsp, 100h ; 開辟棧xor rax, raxmov rax, rcx ; 獲取第一個參數給raxadd rax, rdx ; 第一個參數與第二個參數進行相加mov rax, num ; 獲取全局變量nummov rax,[rax] ; 獲取num的值add rsp, 100h ; 恢復棧ret ; 返回addShu endpend
c/c++代碼
#include <iostream>// 帶著 extern 這個單詞就說明從全局中找,帶著extern它的如果函數名重復了會出現問題
// 在全局中找一個 addShu ,這個addShu函數實用匯編實現的
extern "C" int addShu(int s1, int s2);
extern "C" int num = 999;
int main() {num = addShu(11, 23);printf("num = %d", num);
}