Re: need some help here :(



Zhane wrote:
hmm....

my code is here
http://pastebin.com/m6a19ec93


you see i'm trying to execute INT 1Ah and read off the return values
in EAX,EBX,ECX,EDX etc ( the return values are in this form anyway)

I'm not sure if I should do it in 16 or 32 bit... but the requirement
of INT 1Ah states that I must work in the REAL mode and not the v8086
mode... so I supposed I have to do in 16bit...

but the problem is... when I compile in with 16bit, i either... get
errors cause of the extended registers that I tried to read off(when i
remove .386). having the .386 and compiling as a 16bit seems to work,
but i'm not sure if the values i read off from the 32bit register
values are valid or not..

Hi Zhane,

I'm Nasmist, but I believe Masm uses ".386" for two different purposes: enabling 32-bit instructions, and asking for 32-bit code. Which it does depends on whether ".386" is before or after the ".model" directive, I think. You may have to read the Friendly Masm Manual... (or just try it and see which works)

When Intel went to 32 bit hardware, they employed a "clever trick" or a "horrid kludge", depending on your viewpoint - they used the same opcodes. "mov ax, bx" and "mov eax, ebx" are the same opcode! Which gets executed depends on whether the CPU is in 16-bit mode or 32-bit mode. This is determined by a bit in the descriptor that's loaded into the cs register (the OS has presumably taken care of this for us). This behavior can be toggled with an "operation size override prefix" - 66h - which your assembler will insert... if we've managed to tell it what we want.

So far, it would "work" either way, but consider "mov ax, 1" vs "mov eax, 1". In the first case, "1" is a 16-bit (two byte) value, in the second case it's a 32-bit (four byte) value. B8 01 00 in the first case, B8 01 00 00 00 in the second case. When the CPU encounters "B8", it will "gobble up" two bytes if it's in 16-bit mode, or four bytes if in 32-bit mode. Obviously, if we get this wrong, the CPU will miss the next opcode entirely! For "mov eax, 1" in 16-bit code, the assembler must emit 66 B8 01 00 00 00 - the 66 tells the CPU we want a 32-bit operation, in 16-bit code (one instruction only, and one "toggle" only - 66 66 won't put us back to a 16-bit operation). Similarly if we want "mov ax, 1" in 32-bit code, we need that override. The assembler will take care of this automatically - *if* we've correctly informed it what we're doing. That's why it's important!

There's another complication you may encounter. MS's 32-bit linker won't link 16-bit code. I don't recall the version numbers, but if the banner says "incremental linker" it's the 32-bit one. You want one that says "segmented linker"! If you haven't got it:

ftp://ftp.microsoft.com/Softlib/MSLFILES/LNK563.EXE

To use a bios interrupt (or int 21h or other dos interrupt), you want 16-bit code ('cause the interrupts are 16-bit code). I'm not familiar with int 1Ah with 0BBh in ah - if your documentation says "no v86 mode", this *may* not work in "windowed dos". Generally, bios interrupts indicate an error by setting the carry flag, so you may want to do:

mov ax, 0BB00h
int 1Ah
jnc good
; print "oh sh*t!"
jmp exit
good:
....

If there's an error, the register values are probably meaningless, although ax probably contains an error code.

What's that interrupt *do* anyway? What's "TCG"? How come Ralf doesn't know about this?

Anyway(s)... your code looks pretty good - *might* need to put the ".386" before the ".model small", if what you've got isn't working. Could be "tightened up" a little... you don't need to do "pop ebx"/"mov edx, ebx" - just "pop edx" would work... definitely don't need "mov edx, edx"(!). But it should work. Thanks for posting that - *much* easier to "help" if we can see what you're trying to do! Let us know how it goes...

Best,
Frank


.



Relevant Pages