0
我很新裝配和嘗試學習自己。爲外部呼叫選擇特定的寄存器
到目前爲止,我已經瞭解到,根據從調用者傳遞給被調用者的參數數量,如果只有少量參數傳遞,而不是推/彈操作,只有一些特定的寄存器是用過的。
例如,將參數傳遞給一個交換功能
void asm_swap(int *x, int *y)
時,C編譯器使用寄存器RCX和RDX寄存器傳遞變量的地址(在這種情況下,不需要返回值)。切換從_cdecl到_fastcall沒有任何區別。對於另一功能
int asm_fact(int x)
,也就是計算x的階乘,C編譯器使用RCX傳遞x的值,並且RAX返回所計算的階乘。再次,從_cdecl切換到_fastcall沒有任何區別。
連接到這個問題,我有兩個問題:
- 我可以推斷斷言的是,每當我編譯相同的代碼時,用戶將肯定用於發送和接收數據相同的寄存器?
- 有沒有辦法來選擇特定的寄存器作爲一種工具來傳遞變量(比如,對於功能
asm_fact
,我寧願使用RDX舉行x的值,而不是RCX?
系統:視窗10(64),VS-2013
樣品的編號: 文件 「的main.c」
#include <stdlib.h>
#include <stdio.h>
extern void asm_swap();
extern signed long long int asm_fact();
typedef signed long long int sint64;
sint64 fact_sint64(sint64 n) {
sint64 ret = (sint64)1;
if (n > (sint64)1) {
while (n > (sint64)1) {
ret *= n--;
}
}
return (ret);
}
void swap_sint64(sint64 *a, sint64 *b) {
sint64 t = *a;
*a = *b;
*b = t;
}
int main(void) {
sint64 x, y;
x = 8;
y = 3;
printf("(initial) -> x = %lli y = %lli\n\n", x, y);
swap_sint64(&x, &y);
printf("(swap in c) -> x = %lli y = %lli\n\n", x, y);
asm_swap(&x, &y);
printf("(swap in asm) -> x = %lli y = %lli\n\n", x, y);
y = fact_sint64(x);
printf("(fact in c) -> fact(%lli) = %lli\n\n", x, fact_sint64(x));
y = asm_fact(x);
printf("(fact in asm) -> fact(%lli) = %lli\n\n", x, y);
getchar();
return (0);
}
文件 「Assembly.asm64」
.data
.code
asm_swap proc
mov r8, [rcx]
mov r9, [rdx]
mov [rcx], r9
mov [rdx], r8
ret
asm_swap endp
asm_fact proc
mov rax, 1
cmp rcx, 1
jle [email protected]
[email protected]:
imul rax, rcx
dec rcx
cmp rcx, 1
jg [email protected]
[email protected]:
ret
asm_fact endp
end
1)是2)否。參見[msdn](https://msdn.microsoft.com/en-us/library/zthk2dkh。aspx) – Jester
這是*調用約定*的一部分,它是由實現定義的ABI(*應用程序二進制接口*)的一部分。 – EOF
@Jester:非常感謝。那正是我所期待的。 – ssd