Windows 64 ABI,正确的注册使用,如果我不打电话Windows API?

正如我在另一个问题,我检查了ABI的窗口,我留下了一些困惑,我可以和不能做,如果我不打电话给自己的Windows API。

我的场景是我编程.NET,需要在asm中的一小块代码针对特定的处理器的时间关键部分的代码,在一个arrays上进行繁重的多通处理。

在https://msdn.microsoft.com/en-us/library/9z1stfyw.aspx查看ABI中的注册信息时

如果我对我有什么适用,我会有点困惑

1)不要从asm代码中调用windows API

2)不要返回一个值并采用一个参数。

这是我的理解,我是否正确?

RAX:我可以覆盖这个不保留它,因为函数不期望返回值

RCX:我需要保留这个,因为这是单一的int参数将被传递,然后我可以覆盖它,而不是恢复

RDX / R8 / R9:不应该被初始化,因为在我的方法中没有这样的参数,我可以覆盖那些而不是恢复它们

R10 / R11:如果呼叫者需要,我可以覆盖那些不保存它们的人员,他负责保存它们

R12 / R13 / R14 / R15 / RDI / RSI / RBX:我可以覆盖它们,但我首先需要保存它们(或者如果我不调用Windows API,我可以保存它们吗?

RBP / RSP:我假设我不应该碰那些?

如果是这样,我正确的是,这是处理这个问题的正确方法(如果我不在乎保存数据的时间,并需要尽可能多的寄存器)? 还是有办法使用更多的寄存器?

; save required registers push r12 push r13 push r14 push r15 push rdi push rsi push rbx ; my own array processing code here, using rax as the memory address passed as the first parameter ; safe to use rax rbx rcx rdx r8 r9 r10 r11 r12 r13 r14 r15 rdi rsi giving me 14 64bit registers ; 1 for the array address 13 for processing ; should not touch rbp rsp ; restore required registers pop rbx pop rsi pop rdi pop r15 pop r14 pop r13 pop r12 

你只需要保存你使用的寄存器 。 如果你不使用所有这些,你不需要保留所有这些。

您可以自由使用RAXRCXRDXR8R9R10R11 。 后两者必须由来电者保存,如有必要,不要由您的功能保存。

大多数情况下,这些寄存器(或者像EAX这样的子寄存器)对我来说已经足够了。 我几乎不需要更多。

当然,如果其中任何一个(例如RCX )包含了你的函数的参数,那么只要你需要它们,你自己来保存它们。 你怎么做,也取决于你。 但是,如果你push他们,确保有一个相应的pop地方。

使用此MSDN页面作为指导。

TL; DR:如果您需要标记为已保存的寄存器,请按正确的顺序按下/弹出它们。 通过你的代码,你可以使用你提到的那14个寄存器, 如果你保存它,你可能会碰到RBP,但基本上不要碰到RSP。

如果你打电话给Windows API,但并不像我想的那样。 ABI说什么登记你必须保存。 保存信息意味着主叫方知道有寄存器不会改变。 你不需要调用任何Windows API函数来满足那个需求。

作为一个模拟的想法(是的,我知道…):这里有五个不同颜色的粘滞便笺。 你可以使用它们中的任何一个,但是如果你需要红色或蓝色的,你可以把最上面的那个放在一个安全的地方,当你停下来的时候把它放回去,因为我需要电话号码。 关于其他颜色,我不在乎,他们只是草稿纸,我已经在其他地方写了信息。

所以如果调用一个外部函数, 你就知道没有函数会改变标记为保存的寄存器的值。 任何其他的注册可能会改变他们的价值观, 必须确保你没有任何需要保存的东西。

而当你的函数被调用的时候, 调用者期望的是相同的:如果他们把一个值保存在一个保存的寄存器中,那么在调用之后它将具有相同的值。 但是任何非保存的寄存器可能是任何东西,如果需要保存的话,他们会确保它们存储这些值。

你可以使用你想要的返回值寄存器。 如果函数没有返回值,调用者不能期望它有任何具体的值,也不会期望它保持它的价值。