将Assembler x86 CPU ID代码移植到AMD64

Max*_*xim 6 delphi assembly x86-64 basm delphi-xe3

我有个问题.我遵循用ASM编写的x86 delphi代码.我需要将它移植到AMD64吗?

type
 TCPUID = array[1..4] of Longint;

function GetCID : TCPUID; assembler; register;
asm
  push  ebx
  push  edi
  mov   edi, eax
  mov   eax, 1
  dw    $A20F
  stosd
  mov   eax, ebx
  stosd
  mov   eax, ecx
  stosd
  mov   eax, edx
  stosd
  pop   edi
  pop   ebx
end;
Run Code Online (Sandbox Code Playgroud)

我从未在汇编中编程,有没有人知道端口是什么或我将如何改变它.

klu*_*udg 10

我不是Win64汇编程序大师,但下一个翻译适合我(在64位免费pascal上测试):

program project1;

{$mode delphi}
{$asmmode intel}

type
 TCPUID = array[1..4] of Longint;

function GetCID: TCPUID;
asm
  push  rbx
  push  rdi
  mov   rdi, rcx
  mov   eax, 1
  cpuid
  mov   [rdi],eax
  add   rdi,4
  mov   [rdi],ebx
  add   rdi,4
  mov   [rdi],ecx
  add   rdi,4
  mov   [rdi],edx
  pop   rdi
  pop   rbx
end;

var ID: TCPUID;

begin
  ID:= GetCID;
  Writeln(ID[1], '-', ID[2], '-', ID[3], '-', ID[4]);
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)


Dav*_*nan 6

这是我的版本,适用于x86和x64:

function GetCPUID: TCPUID;
asm
{$IF Defined(CPUX86)}
  push  ebx
  push  edi
  mov   edi, eax
  mov   eax, 1
  xor   ecx,ecx
  cpuid
  mov   [edi+$0], eax
  mov   [edi+$4], ebx
  mov   [edi+$8], ecx
  mov   [edi+$c], edx
  pop   edi
  pop   ebx
{$ELSEIF Defined(CPUX64)}
  mov   r8, rbx
  mov   r9, rcx
  mov   eax, 1
  cpuid
  mov   [r9+$0], eax
  mov   [r9+$4], ebx
  mov   [r9+$8], ecx
  mov   [r9+$c], edx
  mov   rbx, r8
{$IFEND}
end;
Run Code Online (Sandbox Code Playgroud)

关于x64的一个好处是,有更多的寄存器可用,其中许多是易失性的.因此,我们可以利用该临时空间,避免触及主存.显然我们必须触摸主内存才能返回结果.

由于RBX是非易失性的,我们保留其价值.我们修改的所有其他寄存器都是易失的,因此我们不需要保留它们.我想不出有任何方法可以进一步简化这一点.

这可以很容易地扩展,以允许输入CPUID作为参数传递:

function GetCPUID(ID: Integer): TCPUID;
asm
{$IF Defined(CPUX86)}
  push  ebx
  push  edi
  mov   edi, edx
  xor   ecx,ecx
  cpuid
  mov   [edi+$0], eax
  mov   [edi+$4], ebx
  mov   [edi+$8], ecx
  mov   [edi+$c], edx
  pop   edi
  pop   ebx
{$ELSEIF Defined(CPUX64)}
  mov   r8, rbx
  mov   r9, rcx
  mov   eax, edx
  cpuid
  mov   [r9+$0], eax
  mov   [r9+$4], ebx
  mov   [r9+$8], ecx
  mov   [r9+$c], edx
  mov   rbx, r8
{$ELSE}
  {$Message Fatal 'GetCPUID has not been implemented for this architecture.'}
{$IFEND}
end;
Run Code Online (Sandbox Code Playgroud)

假设在ECX中传递的子叶值为0.同样,如果您希望通过它,这很容易:

function GetCPUID(Leaf, Subleaf: Integer): TCPUID;
asm
{$IF Defined(CPUX86)}
  push  ebx
  push  edi
  mov   edi, ecx
  mov   ecx, edx
  cpuid
  mov   [edi+$0], eax
  mov   [edi+$4], ebx
  mov   [edi+$8], ecx
  mov   [edi+$c], edx
  pop   edi
  pop   ebx
{$ELSEIF Defined(CPUX64)}
  mov   r9,rcx
  mov   ecx,r8d
  mov   r8,rbx
  mov   eax,edx
  cpuid
  mov   [r9+$0], eax
  mov   [r9+$4], ebx
  mov   [r9+$8], ecx
  mov   [r9+$c], edx
  mov   rbx, r8
{$ELSE}
  {$Message Fatal 'GetCPUID has not been implemented for this architecture.'}
{$IFEND}
end;
Run Code Online (Sandbox Code Playgroud)