【发布时间】:2019-03-16 11:05:46
【问题描述】:
这是我的第一个问题,因为我找不到与此主题相关的任何内容。
最近,在为我的 C 游戏引擎项目制作课程时,我发现了一些有趣的事情:
struct Stack *S1 = new(Stack);
struct Stack *S2 = new(Stack);
S1->bPush(S1, 1, 2); //at this point
bPush是结构体中的一个函数指针。
所以我想知道,在这种情况下,运算符-> 是什么,我发现:
mov r8b,2 ; a char, written to a low point of register r8
mov dl,1 ; also a char, but to d this time
mov rcx,qword ptr [S1] ; this is the 1st parameter of function
mov rax,qword ptr [S1] ; !Why cannot I use this one?
call qword ptr [rax+1A0h] ; pointer call
所以我假设 -> 写了一个指向 rcx 的对象指针,我想在函数中使用它(它们应该是方法)。所以问题是,我怎样才能做类似的事情
push rcx
// do other call vars
pop rcx
mov qword ptr [this], rcx
在它开始写入函数的其他变量之前。有预处理器的东西?
【问题讨论】:
-
这是一个很大的话题,但基本的答案是您确实在寄存器中传递(一些)参数。你需要了解的概念是calling conventions。
-
@IlyaPakhmutov C 没有“这个”。您是否标记了错误的语言?
-
那么,你为什么要关心编译器使用了哪些寄存器呢?
-
@interjay:我认为 Ilya 的意思是 MSVC 在针对 x86-64 时不允许/支持内联 asm,只有 32 位 x86。当然,阻止您使用内联 asm 的不是 x86-64,而是 Microsoft 的编译器。其他编译器(gcc、clang、ICC)在面向 x86-64 Windows 时都允许 GNU C 内联 asm 语法。但是你必须自己编写约束和破坏。
-
如果有的话,我会试图说服 MSVC 使用它已经在 RCX 中拥有的
S1的副本作为call寻址模式的基础,而不是浪费一条指令来加载再次 S1。我怀疑您正在查看未优化的代码,尽管 MSVC 可能在那里错过了优化。
标签: c assembly visual-c++ x86-64 calling-convention