Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Indirect Addressing (32-bit)

PHM555PHM555 Member Posts: 7

I'm still trying to get used to the newer processors after returning to assembly programming after a long hiatus.
I had thought that 32-bit register indirect addressing (e.g., mov [ebx], eax) used a continuous addressing method without needing to resort to the segment registers, but perhaps I was mistaken?
I'm trying to pass a 32-bit pointer from a C++ program to a chunk of machine code which I load at run-time and then call via inline assembly. It works fine unless the machine code tries to store memory via the pointer. I had been passing the pointer via the ebx register - i.e., I place the pointer in ebx via inline asm, then call the machine code chunk via inline asm, and this code is then supposed to be able to use ebx to access a section of memory.
Do I need to set the ds register as a 'base', like we used to do back in the Dark Ages of 16-bit processors? I thought the modern 32-bit processors finally did away with that?
If the segment registers still need to be used, what is the offset limit - i.e., if ebx is the offset, can it access a full 4 gb beyond the base, or is it limited to 64k despite being a 32-bit register ?

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]There is no need for segments - something else is wrong in code. Can you post the code? To execute the code at run-time you need to allocate memory which has EXECUTE property - only then code will be called properly. Also, EBX may be damaged before you pass the execution onto your code piece. Without the actual code - I can't help much. If you do not want to post code here - my email is: asmguru62@hotmail.com[/color]
  • PHM555PHM555 Member Posts: 7
    : [color=Blue]There is no need for segments - something else is wrong
    : in code. Can you post the code? To execute the code at run-time you
    : need to allocate memory which has EXECUTE property - only then code
    : will be called properly. Also, EBX may be damaged before you pass
    : the execution onto your code piece. Without the actual code - I
    : can't help much. If you do not want to post code here - my email is:
    : asmguru62@hotmail.com[/color]

    Thank you. My program used to work fine when I had it generate its own machine code via a simple compiler that I wrote for my own (very simple) language; but when I decided to scrap that and use precompiled code generated by FASM, calling the code no longer works correctly. More precisely: the runtime machine code chunk sometimes works (or at least doesn't cause a crash) depending on what the code is, but there isn't any rational pattern to it - which is one reason I had thought that maybe the code was being garbled by the method I was using to read the file, but changing it to fread (which shouldn't have any conversion problems) didn't fix the problem.
    Here's the portion of the C++ program which calls the runtime machine code - although this part of the program hasn't changed since the old version which used to work, hence it's unlikely to be the source of the problem:
    CodeAddr = (DWORD)(RuntimeCodeBuffer);//pointer to machine code
    asmframebuf = (DWORD)(framebuf);//screen buffer for graphics
    __asm ("push %eax");
    __asm ("push %ebx");
    //code below places codeaddr in eax -- AT&T syntax is backwards
    __asm ("mov _CodeAddr, %eax;");
    __asm ("mov _asmframebuf, %ebx;");//passing asmframebuf via ebx
    __asm ("call * %eax");//call runtime machine code
    __asm ("pop %ebx");
    __asm ("pop %eax");

    I'm not sure what other portions of the code you wanted to see - it's a reasonably large program.

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]Pointer 'RuntimeCodeBuffer' should have the EXECUTABLE property. Check VirtualAlloc() for details. Are you coding for Win32?[/color]
  • PHM555PHM555 Member Posts: 7
    : [color=Blue]Pointer 'RuntimeCodeBuffer' should have the EXECUTABLE
    : property. Check VirtualAlloc() for details. Are you coding for
    : Win32?[/color]


    Yes, Win32. And I've confirmed that the machine code sometimes runs correctly because I can get it to change the eax register and then have some inline asm code store eax in the graphics buffer, producing a line with whatever color the runtime machine code changes eax to (e.g., eax = 0x00FF0000 produces a red line on the screen).
    Here's my code for allocating and changing access protection for the runtime buffer (minus error checking code):

    RuntimeCodeBuffer = (byte *) VirtualAlloc(NULL,RuntimeCodeBufferSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
    . (error checking removed for sake of brevity)
    .
    DWORD VPOldProt;
    BOOL VPStatus = VirtualProtect((LPVOID)RuntimeCodeBuffer,RuntimeCodeBufferSize,PAGE_EXECUTE_READWRITE,&VPOldProt);
    . (error checking removed for sake of brevity)
    .

    BTW, here's an example of the strange results that I get with different machine code chunks:

    The code below works:
    mov eax, 0x000000FF ; (produces a bright blue line)
    ret

    But this crashes:
    mov eax, 0x00FFFFFF ; (should be a white line)
    ret

    This also crashes:
    mov eax, 0x00FFFF00 ; (should be a yellow line)
    ret

    But this works:
    mov eax, 0x00FF0000 ; (produces a red line)
    ret

    This also works:
    mov eax, 0x00FE0000 ; (slightly darker red)
    ret

    But this crashes - even though only the same byte is being altered
    mov eax, 0x00FA0000 ; (darker red than the above)
    ret

    Obviously, changing the number shouldn't cause a crash. This is why I initially thought the code was getting garbled when reading the file, but I've ruled that out after testing it by saving the contents of the runtime code buffer and then comparing it to the original file. They are identical. So I have no idea what's going on. The code is clearly being run in 32-bit mode since using 'red' (0x00FF0000) works fine although this number is obviously stored as 00 00 FF 00 (low-high) and hence would not work correctly if only the low 16 bits were being loaded rather than all 32.


  • PHM555PHM555 Member Posts: 7

    Could the problem be caused by Windows' Data Execution Prevention 'feature'? I.e., it might be interpreting certain byte sequences as a potential risk, and shutting down the program if those sequences are found in the machine code? This might explain the odd pattern, and also the fact that whenever it 'crashes' I just get a window saying that it has "stopped working".
    I'm using Windows Vista, which is said to be a developer's nightmare and has all the latest (overbearing) security headaches added to it.
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]If you are writing directly into video memory - your code should run as a driver code. In which context your code is running? Are you doing all that as an application or a driver? Because, looks like that Execution Prevention feature is not letting you do ALL YOU WANT.[/color]
  • PHM555PHM555 Member Posts: 7
    I'm not directly accessing video memory - I'm using a Device Independent Bitmap which is then displayed by Windows. My program does nothing but write to the bitmap array.

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]I see... without really debugging this code I am out of ideas.[/color]
Sign In or Register to comment.