先看这个过程:
procedure TForm1.GetCpuInfo(var ResultStr: String);
var
  R: array[0..19] of Char;
  CpuID: Integer;
  R1,R2 : String;
begin
  //ResultStr := '';
  FillChar(R, 20, 0);
  asm
    mov eax, 0
    db 0fh, 0a2h               
    mov dword ptr R[0],  ebx
    mov dword ptr R[4],  edx
    mov dword ptr R[8],  ecx
    mov eax, 1
    db 0fh, 0a2h               
    mov CpuID, edx
  end;  ShowMessage('CPU制造商为:' + R);
  ShowMessage('序列号为:' + IntToStr(CpuID));
 // R1 := R;
 // R2 := IntToStr(CpuID);
 // R1 := R1+R2;
 //ResultStr := R1 ;
 //or Result := Copy(R1, 1, Length(R1));
end;此时主函数调用该过程是正确的,功能很清楚.
问题是如果想让调用该过程的函数得到正确的R 和cpuid的值,怎么实现呢?
注释的那部分如果取消掉,运行时候会报地址访问冲突错的.(windows2000)哪位解释清楚并且解决了立即给分.

解决方案 »

  1.   

    将    "procedure TForm1.GetCpuInfo(var ResultStr: String);" 
    改为  "function TForm1.GetCpuInfo(var ResultStr: String):boolean;" 
    就可以了,
    因为过程"procedure" 是不支持这样传递参数的,
    只有函数"function" 可以这样做.另外,谢谢你的汇编代码!
      

  2.   

    又学到了知识,今天没白来CSDN。
      

  3.   

    灌水》》》》》》》》  asm
        PUSH    EBX         {Save affected register}
        PUSH    EDI
        mov eax, 0
        db 0fh, 0a2h
        mov dword ptr R[0],  ebx
        mov dword ptr R[4],  edx
        mov dword ptr R[8],  ecx
        mov eax, 1
        db 0fh, 0a2h
        mov CpuID, edx
        POP     EDI {Restore registers}
        POP     EBX
      end;to Mozh(Alex) procedure也可以传递变参
      

  4.   

    学习
    谢谢findya不过这个问题的确可以通过将 "procude" 改成 "function" 解决
      

  5.   

    问题出在汇编代码上,编译器通过寄存器传递参数,你的汇编代码改变了寄存器的值,因此字符串参数的地址丢失了,你访问的时候自然会报错,如果你的汇编代码中加入push,pop操作保存参数地址就不会报错了。
    push ebx
    ...
    pop ebx
      

  6.   

    回答不完全正确!在DELPHI中嵌入ASM不需要利用push(压栈),Pop(从栈中弹出)的操作来保存使用前的寄存器状态,因为DELPHI编译器已经帮你做了这些!问题的关键是这句ResultStr := R1 ;学过第二代高级语言都需要对形参,实参的概念有些了解!返回参数直接利用函数就好了!
      

  7.   

    function GetCpuInfo:String;
    var
      R: array[0..19] of Char;
      CpuID: Integer;
      R1,R2 : String;
    begin
      Result:= '';
      FillChar(R, 20, 0);
      asm
        mov eax, 0
        db 0fh, 0a2h               
        mov dword ptr R[0],ebx
        mov dword ptr R[4],edx
        mov dword ptr R[8],ecx
        mov eax, 1
        db 0fh, 0a2h               
        mov CpuID, edx
      end;
      ShowMessage('CPU制造商为:' + R);
      ShowMessage('"序列号"为:' + IntToStr(CpuID));
      R1 := R;
      R2 := IntToStr(CpuID);
      R1 := R1+R2;
      Result:= R1;
    end;其实在MASM,TASM的例程中都有调用CPUID指令的例子!不过写这代码的人确实在误导人?那是序列号吗?除了早期的P3,对其它INTEL和AMD CPU来说,根本就测不出序列号!调用功能1(EAX=1)后,32位寄存器EDX返回的是CPU特征标志字!从0到31分别是!0       FPU On-chip                          FPU
    1       Virtual Mode Extension               VME
    2       Debugging Extension                  DE
    3       Page Size Extension                  PSE
    4       Time Stamp Counter                   TSC
    5       RDMSR/WRMSR Instructions
    6       Physical Address Extension           PAE
    7       Machine Check Exception              MCE
    8       CMPXCHG8B Instruction
    9       On-chip APIC HardWare
    10      Undefined
    11      SYSENTER/SYSEXIT Instructions
    12      Memory Type Range Registers
    13      Page Global Enable                   PGE
    14      Machine Check Architecture           MCA
    15      Conditional Move Instruction         CMI
    16      Page Attribute Table                 PAT
    17--22  Undefined
    23      MMX Instructions                     MMX
    24      internet Streaming SIMD Extensions   SSE
    25--31  Undefined
      

  8.   

    当然可以优化程序,嵌入汇编一般用于优化程序,调用CPU扩展指令集(MMX,SSE,3D NOW...),进行一些对系统底层的调用!
      

  9.   

    同意ehom的说法,只有早期的P3有序列号,之前都没有,但后来的还有没有好像就没再讲过了.
      

  10.   

    我faint.
    引出这么一堆东西啊
    这么点分乱给得了,