Reputation: 469
So one of our projects has hit a snag with some assembly code that needs to be written. We have an old, old (compiled with Borland 1992) memory tester C program that occasionally needs to drop to assembly to read values from certain areas of memory. I need to write a MASM assembly routine that takes in a 32 bit memory address and return the dword at that location. My only assembly experience was about 4 years ago in MIPS, so I'm pretty rusty. So far, I have this:
; 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
The problem is when I read in values, I get something that is almost, but not quite, what I'm looking for. When I run something like...
DWORD output = mmap_io(0xEFF87110);
printf("output: %p\n");
output = mmap_io(0xE0000000);
printf("output: %p\n");
On a memory space where 0xEFF87110 has the value 0x00000000 in it, and 0xE0000000 has 0x80863C00 in it, I end up getting:
output: 0110:0000
output: 9463:8086
I believe that I'm mixing up my 16 bit and 32 bit registers, but any attempts to fix these have resulted in further problems. Does anyone have some better, cleaner code for reading directly from a 32 bit memory address, or can help me fix my problem?
Upvotes: 0
Views: 1195
Reputation: 98505
This can be done in good old C. No need for assembly. Assuming that a "dword" is 32 bits:
#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;
}
Similar versions can be had for 16- and 8-bit values.
Upvotes: -1