【发布时间】:2012-06-01 19:42:48
【问题描述】:
因此,我们的一个项目遇到了一些需要编写的汇编代码的障碍。我们有一个旧的、旧的(用 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 位内存地址读取,或者可以帮助我解决我的问题?
【问题讨论】:
-
只需使用 32 位寄存器而不是 16 位。 32 位带有“e”前缀。 ESP EBP ESI EDI EAX EBX EDX ECX
-
该代码已有 20 年历史,适用于 MS-DOS 或 Windows 2.0。事情不再那样工作了!
-
没有足够的信息来调试这个程序。您编写的汇编代码应该会崩溃,因为它正在运行保护模式并且您已将 NULL 选择器加载到 ES 中,或者因为您正在运行实模式并且
0xEFF87110超过了 16 位实模式段限制。跨度>