我在王爽书上看到一个例子:mov ax,2000h
mov ds,ax
mov bx,1000h
mov ax,[bx]
inc bx
inc bx
mov [bx],ax
......这是一个就内存中21000h~~21007h单元内容的例子,其中21000h内容为'BE',21007h内容为'00'(第5章 问题5.1)
这个例子我能理解。然后我在delphi中function TForm1.A10(i:integer):integer;
begin
  asm
    mov ecx,1000h
    mov eax,1500h
    mov [eax],ecx     ---------------    (1)
    mov result,eax
  end;
end;function TForm1.A11(i:integer):integer;
begin
  asm
    mov ecx,1000h
    mov eax,1500h
    mov [ecx],1h       ---------------    (2)
    mov eax,[ecx]      ---------------    (3)
    mov result,eax
  end;
end;
在调用它们时,(1)(2)(3)处有[]处,都会报内存错误。
我想问下在delphi中,函数里用eax等寄存器,都只是当变量使用(其中的含义异于一般汇编语句)?还是因为该地址内存不可改?还是什么别的原因?
在delphi的函数中能不能用[],怎么用?菜鸟问题,请多帮助,谢谢。

解决方案 »

  1.   

    你看看Windows单元,里面有很多例子。其他单元也有
      

  2.   

    []表示地址,当然可以用。
    出错是因为你给出的地址有问题,在win32的程序模型中,虽然有4GB地址空间,但是不是都可使用的,2GB~3GB是用于程序引用的DLLs,3GB以上用于系统内核,低2GB的高低两端各64KB用于捕获NULL指针操作(你程序中用到的地址恰好就位于低64KB之内),也不可访问。即便剩余的不足2GB空间,也要先分配再使用,否则就是“虚”的,只有地址,没有物理内存与之对应。
      

  3.   

    这样改一下:
    function TForm1.A11(i:integer):integer;
    var
      a, b: integer;
    begin
      asm
        lea ecx,a
        lea eax,b
        mov [a],1h
        mov eax,[a]
        mov result,eax    // 这句其实没用,去掉也可以
      end;
    end;
      

  4.   

    DelphiGuy不厚道。只帮小孩子抓鱼,不教小孩子抓鱼。
      

  5.   


    我看这句还是留着吧,我这样
    function TForm1.A10(i:integer):integer;
    begin
      asm
        mov eax,edx  //或用mov eax,i 
      end;
      showmessage('aa');
    end;
    它的返回值就不对了。还有edx是不是默认接收第一个参数值?我怎么感觉有时是有时不是?不同的版本也会不同吧?
      

  6.   

    返回值就在eax(或者edx:eax=int64)中,所以这句mov result,eax 一点用没有,你反汇编看就是mov eax,eax。
    至于你举的例子,后面的showmessage('aa');又使用了eax,你之后又没有再设置返回值,当然就不对了。没有任何版本的Delphi“edx默认接收第一个参数值”,对于Delphi默认的register调用约定,eax、edx、ecx包含3个参数(如果有的话),但是有一个例外:浮点参数永远不使用寄存器传递。
      

  7.   

    eax、edx、ecx包含前3个参数(如果有的话)
      

  8.   


    '对于Delphi默认的register调用约定,eax、edx、ecx包含3个参数(如果有的话)' 对于这个我想问下:如C++中是否就不同了呢?还是对所有的语言都是'默认的register调用约定,eax、edx、ecx包含3个参数(如果有的话)'?
    如果不是的话,那这些资料(如'eax、edx、ecx包含前3个参数(如果有的话)',eax默认作为返回值)从哪里可以学习到?(看delphi源码?+经验积累?)因为一般的 汇编 教程的话不会讲这些吧。
      

  9.   


    这是与编译器相关的,不同的编译器处理参数的方法不能保证一样。
    Delphi和C++ Builder的参数处理方法是一样的,Delphi的register调用约定在C++ Builder中叫__fastcall,
    但是ms的编译器就和Delphi/C++ Builder处理参数的方法不同,VC++的__fastcall是用ecx、edx传送前2个参数(注意是左面开始的两个),这种调用约定在C++ Builder中叫__msfastcall。
    这些在帮助文档中都有的。
      

  10.   

    王爽这书我也在看.
    书里面不停的说用cmd-debug写汇编程序,郁闷死人了.
    汇编程序或者语句用什么写?
    大家推荐下.
      

  11.   

    前面说的只是针对register/fastcall调用约定,对一些“标准”的调用约定,象cdecl、pascal、stdcall等,不同的编译器之间还是遵循相同的标准的。