C ++外部程序集:我的代码中哪里出错?

时间:2015-02-03 15:38:44

标签: c++ assembly x86

的main.cpp

// Calls the external LongRandom function, written in

// assembly language, that returns an unsigned 32-bit

// random integer. Compile in the Large memory model.

// Procedure called LongRandomArray that fills an array with 32-bit unsigned 

// random integers

#include <iostream.h>

#include <conio.h>

extern "C" {

          unsigned long LongRandom();

          void LongRandomArray(unsigned long * buffer, unsigned count);

           }

const int ARRAY_SIZE = 20;

int main()

{

  // Allocate array storage and fill with 32-bit

  // unsigned random integers.

  unsigned long * rArray = new unsigned long[ARRAY_SIZE];

  LongRandomArray(rArray,ARRAY_SIZE);

  for(unsigned i = 0; i < 20; i++)

  {

    cout << rArray[i] << ',';

  }

  cout << endl;

  getch();

  return 0;

}

LongRandom&amp; LongRandomArray过程模块(longrand.asm)

.model large

.386

Public _LongRandom

Public _LongRandomArray

.data

seed  dd 12345678h

; Return an unsigned pseudo-random 32-bit integer

; in DX:AX,in the range 0 - FFFFFFFFh.

.code

_LongRandom  proc far, C 

      mov   eax, 214013

      mul  seed

      xor   edx,edx

      add   eax, 2531011

      mov   seed, eax    ; save the seed for the next call

      shld  edx,eax,16   ; copy upper 16 bits of EAX to DX

      ret

_LongRandom  endp

_LongRandomArray  proc far, C 

ARG bufferPtr:DWORD, count:WORD

; fill random array

      mov edi,bufferPtr

      mov cx, count

L1:

     call _LongRandom

     mov word ptr [edi],dx

     add edi,2

     mov word ptr [edi],ax

     add edi,2   

     loop L1

     ret

_LongRandomArray  endp

end

1 个答案:

答案 0 :(得分:0)

此代码基于来自Kip Irvine的汇编书(第6版)的MS-DOS的16位示例,并且明确地为Borland C ++ 5.01和TASM 4.0编写(参见第13.4章和第34章;在实地址模式下链接到C / C ++&#34;)。

16位模式的指针由段和偏移量组成,通常写为segment:offset。这是将由处理器计算的实际内存地址。您可以在32位寄存器(segment:offset)中加载EDI并将值存储到内存中。所以

...
mov edi,bufferPtr
...
mov word ptr [edi],dx
...

错误。您必须在段寄存器中加载指针的段部分,例如ES,适当的通用16位寄存器中的偏移部分,例如。 DI并可能使用段覆盖:

...
push es
les di,bufferPtr         ; bufferPtr => ES:DI
...
mov word ptr es:[di],dx
...
pop es
...

ARG用适当的[bp+x]操作数替换变量的名称。因此,你需要一个序幕(和结语)。 TASM插入正确的指令,如果PROC标题写得很好,那么这里不是这种情况。看看下面的工作函数:

_LongRandomArray PROC C FAR
ARG bufferPtr:DWORD, count:WORD
    push es
    les di,bufferPtr
    mov cx, count
L1:
    call _LongRandom
    mov word ptr es:[di],dx
    add di,2
    mov word ptr es:[di],ax
    add di,2
    loop L1
    pop es
    ret
_LongRandomArray ENDP

使用BCC编译代码( BCC32):

BCC -ml main.cpp longrand.asm