using SI/DI in my code, which crashes as ESI/EDI is actually used

Started by DaveM, August 17, 2009, 08:59:26 PM

Previous topic - Next topic

DaveM

If I have SI or DI in one of my operands, how come if I build a console application the actual code that gets executed uses ESI or EDI?  I didn't specify the top 16 bits and assumed it was irrelevant as I had specified the 16 bit version of the register in my code.   My instruction caused a crash as the actual code that I saw in the dissasembly used ESI and there was some random value in the top 16 bits causing an access violation when wrong address was calculated..

Perhaps I can get round this problem by making my small bits of code run as proper 16 bit  8086. I think this is called real mode of 8086 emulation mode.

dedndave

that sounds very strange
but, if you want to use esi/edi for string instructions in a 32-bit program, you must fill esi and edi with 32-bit addresses
it's not hard to change

        mov     esi,offset sourceString
        mov     edi,offset destString
        mov     ecx,stringLength
        rep     movsb

Slugsnack

can you show your code ? if it's a function call then to align the stack then a movzx may be performed prior to a push

if it's one of the string 'macro opcodes' like scasb, etc. then those may require the whole register as well

dedndave

yes - you should put some code in here - that would make it much easier for us to see what is going on
either way...
Quoteif you want to use esi/edi for string instructions in a 32-bit program, you must fill esi and edi with 32-bit addresses

when i post code in here, i use the "teletype" anchor from the icons above the reply window
or, preceed the code with [ tt ] <-- remove the spaces
and end it with [ /tt ] <-- remove the spaces

btw - welcome to the forum
name is Dave - can't be all bad - lol

DaveM

Well it was really basic(sorry) code.

ARRAY_START DB 0,1,2,3,4,5,6,7,8,9


ADD AL,ARRAY_START[4]     ; fine

MOV SI,4
ADD AL,ARRAY_START[SI]  ; crashes

MOV DI,4
ADD AL,ARRAY_START[DI]  ; fine

now when I got into Visual studio and saw the dissasemby it was because it was using ESI and EDI, for EDI the top 16 bits were 0, but for ESI the top 16 bits had some bits set, so the effective address calculation was screwed. That's why it was using working when I specified DI as by fluke it the top half of EDI was clear.

Of course I could get around this easily by just specifying ESI/EDI in my code, but I'm sure there is a way to make your exe run as a virtual 8086 machine.


dedndave

MOV ESI,4
ADD AL,ARRAY_START[ESI]

MOV EDI,4
ADD AL,ARRAY_START[EDI]


all addresses in a 32-bit program are 32 bits wide
intel didn't give us many instructions that allow a smaller width register to access a wider address
the only one i know of is XLAT

DaveM

Yeah, but there is  a way to switch an exe so that it mimics a bog standard 8086 with all 16 registers and 1Mb address space like a pure 8086 behaves. It's probably assembler or linker options I think.

I'm gonna be rich soon. I feel so happy

dedndave

congrats - but wouldn't it be nice to be rich AND proficient at code ? - lol
here is an example of using XLAT that may interest you...

        mov     ebx,offset ARRAY_START  ;base in ebx
        mov     al,4                    ;index in al
        xlat                            ;loads the value from [ebx+al] into al

from what i understand, xlat is somewhat sluggish, though

but, what you are talking about is writing a 16-bit program
you need a different linker (link16.exe or lnk563.exe)
that is a move backwards - believe me, you want to stick with 32-bit programs
ms is slowly making 16-bit code obsolete

EDIT
with wealth comes power
with power comes responsibility
you should keep compassion in your heart and see to it that others less fortunate are helped
send me some money - i can pm you with my pay-pal account

GregL

Quote from: dedndavems is slowly making 16-bit code obsolete

It already is obsolete in 64-bit Windows.


Rockoon

Quote from: Greg on August 17, 2009, 11:32:38 PM
Quote from: dedndavems is slowly making 16-bit code obsolete

It already is obsolete in 64-bit Windows.



To be entirely accurate, its obsolete in any 64-bit operating system which runs on Intel/AMD (Unix, Linux, Windows, and even OSX)

The 64-bit mode *replaces* 16-bit mode. A 64-bit kernel cannot thunk to 16-bit code, ever.
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

hutch--

DaveM,

The general drift is use 32 bit code if it has to run under a 32 bit OS, if you really need to write 16 bit code that runs under DOS emulation or in real DOS, write that code form and use a 16 bit linker that produces the correct executable format. The two forms don't mix as 16 bit DOS code runs in a segment/offset addressing mode where 32 bit Windows code runs in flat addressing mode, 0 to 4 gig.

Any address in 32 bit mode is done as a 32 bit unsigned integer, you cannot use a 16 bit address in 32 bit mode.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

DaveM

Ok I hear what you're saying. Interesting to note that there is a linker that will do it.

I think VM bit in EFLAGS could do what I want theoretically but applications wouldn't be able to set that and only the ring 0 code could do it.

Sorry to get over excited about world domination in my first post. I've erased all that now. What I was happy about is that I've found a great forum for hardcore programming. The truth is the CEO/CTO/Chief Floor Sweeper/Dog Catcher (I'm all of those in my company) have created a corporate plan - basically the target is to avoid starvation.

dedndave

good plan
simple, vital, yet achievable   :U

in 32-bit programs, you can access the eflags register without ring 0 permission
one way is...

        pushfd
        pop     eax

        push    eax
        popfd

DaveM

I'm also really relieved to know there are cool people out there doing assembler, after having to suffer decades of high level shit working in all the big companines.  Eventhough I'm starving I feel much more alive than before for sure.