0
votes

I am trying to learn more about x86 assembly (masm) and how it deals with memory. Specifically, I came across the following statement:

mov eax,ds:0x83f413c

I understand this copies the contents on memory address 0x83f413c into eax and this raised the questions. Can I just read from and write to every memory location? How do I know if 0x83f413c even is a valid memory location?

1
Usually we pick the memory locations to read/write by using assembler directives and declaring storage, e.g. globals, which we can refer to by their labeling, or by invoking operating system calls or library functions that dynamically return a pointer to some available memory, or by allocating stack space, which is done relative to the stack pointer. For most purposes, we don't have to know any absolute addresses in advance. If you see that, it needs to be understood within its context -- we can't just expect that to work an any setting.Erik Eidt
You can try to read and write any memory location. If you are not allowed to do so, an exception is raised.fuz

1 Answers

3
votes

Context is everything :) If the line was found in a loaded userland program (which the OP doesn't mention, but I'm going to presume), here's probably how it originated. The mov instruction was reading a valid DWORD sized variable from the program's data section, and the module was either loaded at its preferred load address, or contained a relocation record that would adjust the address in the mov command to the correct address.

The ds: prefix was just a case of disassembler trying to cover all bases. The mov reg, mem command uses ds by default.

In general, you can't access any old address. HOWEVER, any program needs some memory - at the very least to store its statically declared variables. When the OS loads the program, it has to allocate some memory for the code and the data. The layout of the program in the memory, once it's loaded, is predictable. The linker knows that if the program was loaded starting from, say, 0x8300000, its variable called foo will be found at 0x83f413c. So reading the value of that variable can be coded directly - assuming the program was loaded at its preferred address, which in this example is 0x8300000. The preferred address is stored in the program header so that the OS knows it while loading.

What if the program is NOT loaded at the preferred address? Then there's another technique in play, it's called relocation. The program header contains a set of records that tell the loader to adjust the code while loading. Something like: "in the code section at offset 0x7000 there's a mov reg, mem command that's using a memory offset that's relative to the loading address, please adjust accordingly". The program loader, which is a part of the OS, sees that and does as told.

All in all, a mov command like this, i. e. reading from a static address, can be safe, as long as it's being generated by the build toolchain (compiler/linker) that knows what it's doing. With some help from the OS-based program loader, static addresses like this are safe to work with.


All that was written from the assumption that the OP encountered the line in question in a compiled userland program targeting a protected mode OS (Windows, Linux, etc.). If it was, say, in a device driver or in an OS kernel, or a bootloader, or a real mode 32-bit program (those exist!), then different considerations would apply.