0

そのため、私たちのプロジェクトの1つが、作成する必要のあるアセンブリコードで問題にぶつかりました。古い、古い(Borland 1992でコンパイルされた)メモリテスタCプログラムがあり、メモリの特定の領域から値を読み取るためにアセンブリにドロップする必要がある場合があります。32ビットのメモリアドレスを取り込んでその場所にdwordを返すMASMアセンブリルーチンを作成する必要があります。私の唯一の組み立て経験は約4年前のMIPSでしたので、私はかなり錆びています。これまでのところ、私はこれを持っています:

; Do a direct read of a memory address
public _mmap_io
_mmap_io PROC FAR

push  bp          ; 'C' entry    

mov   bp,sp       ; set pointer to parm list
push  es
xor   ax, ax      ; clear ax        
mov   es, ax      ; clear es?
add   bp, 6       ; bump to parms

xor eax,eax       ; clear eax
mov eax, [bp]     ; move the value pointed to by bp into eax
mov esi, eax      ; source index
mov eax,es:[esi]                           

pop   es    
pop   bp          ; 'C' exit    
ret

_mmap_io ENDP

問題は、値を読み取ると、探しているものとほぼ同じですが、完全ではないものが得られることです。私が何かを実行すると...

DWORD output = mmap_io(0xEFF87110);
printf("output: %p\n");

output = mmap_io(0xE0000000);
printf("output: %p\n");

0xEFF87110に値0x00000000が含まれ、0xE0000000に0x80863C00が含まれるメモリ空間では、次のようになります。

output: 0110:0000
output: 9463:8086

私は16ビットと32ビットのレジスタを混同していると思いますが、これらを修正しようとするとさらに問題が発生します。誰かが32ビットメモリアドレスから直接読み取るためのより良い、よりクリーンなコードを持っていますか、または私の問題を解決するのを手伝ってくれますか?

4

1 に答える 1

-1

これは、古き良き C で実行できます。アセンブリは必要ありません。「dword」が 32 ビットであると仮定すると、次のようになります。

#include <stdint.h>

uint32_t peek32(uintptr_t address)
{
   volatile uint32_t * ptr = (volatile uint32_t *)address;
   return *ptr;
}

void poke32(uintptr_t address, uint32_t value)
{
   volatile uint32_t * ptr = (volatile uint32_t *)address;
   *ptr = value;
}

同様のバージョンは、16 ビット値と 8 ビット値で使用できます。

于 2012-06-01T19:51:01.243 に答える