0

因此,我们的一个项目遇到了一些需要编写的汇编代码的障碍。我们有一个旧的、旧的(用 Borland 1992 编译的)内存测试器 C 程序,它偶尔需要进入汇编程序以从内存的某些区域读取值。我需要编写一个 MASM 汇编例程,它接受 32 位内存地址并返回该位置的 dword。我唯一的组装经验是大约 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 回答