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.
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
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
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
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.
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
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
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
Quote from: dedndavems is slowly making 16-bit code obsolete
It already is obsolete in 64-bit Windows.
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.
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.
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.
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
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.