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