News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

problem with masm

Started by ninjarider, September 07, 2005, 05:25:34 PM

Previous topic - Next topic

MichaelW

You should get the same result for both. If AL=13 then CMP AL,13 and XOR AL,13 will both set the zero flag, so the jump will be taken.

eschew obfuscation

ninjarider

well for some reason it wont take the jump. i dont know y. i'll disassemble it later to see if its compiling correct.

ninjarider

ok really wierd.
using .386

mov ah, 0eh
mov al, 41h
int 10h

displays the letter A

mov ax, 0e41h
int 10h

does absolutly nothing, even keeps my floppy running untill i reboot into windows.

mov ax, 0e41h
mov ax, 0e41h
int 10h

or

mov ax, 0e41h
int 10h
int 10h

either or works. displays A

mov ax, 0e41h
nop
int 10h

gets the bios stuck in a loop filling the screen with "^A"
is my computer stupid?????

AeroASM

Yes. When I was developing my OS I got really annoyed at that. mov ax does not work but if you do ah and al separately it works.

ninjarider

thnx now i atleast know its not me. helps keep the sanity

MichaelW

ninjarider,

With 16-bit segments the code you posted works normally. I think the problem is that you are specifying 32-bit segments, probably by placing the .386 directive above the model directive. Again, see "Setting Segment Word Sizes (80386/486 Only)" here:

http://webster.cs.ucr.edu/Page_TechDocs/MASMDoc/ProgrammersGuide/Chap_02.htm

I can't test this right now, but I suspect that under DOS this code would behave normally. IOW I suspect that the problem here is in the way Windows handles the code. Under Windows 2000 I can correct the problem by substituting EAX for AX. You should expect problems calling BIOS functions that take address arguments from a segment where the default address size is 32 bits.

eschew obfuscation

ninjarider

well the thing is that im not dealing with windows or dos. most of this topic is my adventures into writing an operating system just so i could say i did it. from the interrupt list that i have the bios uses 16-bit segments but the os i was coding used 32-bit just so that i dont have to deal with the 64k limit. even if it was the segment size that wouldn't explain y if the statements are doubled that it works which is y i posted the question the way i did. i'll read you link thou. might prove of use somewere else.

MichaelW

Quotewell the thing is that im not dealing with windows or dos

But you are running your code under Windows, and describing problems that you are having under Windows. I was trying to point out that the problem, at least with the AX versus AH/AL thing, might be Windows.

Quotei was coding used 32-bit just so that i dont have to deal with the 64k limit

Using 32-bit segments will not, in itself, change the 64KB limit. To change the 64KB limit you must change the segment limits that the processor is using, and to do that you must switch to protected-mode, at least temporarily.

eschew obfuscation

Gustav

> even if it was the segment size that wouldn't explain y if the statements are doubled

It is not the segment size. with the directive .386 you are telling MASM that it should generate code for a "32bit code segment". Such code usually can only be executed in protected mode, something which isn't true for your boot loader code.

And then, why does it work somehow?

Your code (32bit code):

mov ax, 0e41h      ;66 B8 41 0E
int 10h                 ;CD 10
int 10h                 ;CD 10

if this code is executed in real-mode the cpu will "interpret" the opcodes as:

mov eax, 10CD0E41h   ;66 B8 41 0E CD 10
int 10h                       ;CD 10

thus it works (HIWORD of EAX is ignored by this interrupt), but just by chance!


ninjarider

MichaelW,
  my appolagies. maybe in the begining i should have mention the way i test and assemble my code. while in windows i edit the code and when i think im done adding code for the moment i assemble it and run debug from the command prompt which then writes the boot sector on the floppy disk. then using the old ctrl+alt+del restart the computer loading my boot code. so there is no windows/dos bullshit to deal with.

gustav,
  hmmmm.... interesting.

ok. so i cant initially use 32-bit code for a boot loader. (weres that intell architecture manual.) from what i read theres not many advantages to protected mode besides the restriction to programs. so hummm... damn computer.

MichaelW

One disadvantage of protected mode is that you cannot reasonably utilize the BIOS functions. A viable alternative is big-real mode, aka unreal mode, which can allow you to use 32-bit addresses and the BIOS functions, other than those that switch to protected mode. Basically, to enter big-real mode you switch to protected mode, load segment descriptors with suitable segment limit values into the descriptor caches (by loading the segment registers), and switch back to real mode. Thereafter, values loaded into the segment registers (in real mode only) will change the segment base, but not the segment limit.

eschew obfuscation

tenkey

Just keep in mind what kind of code you're generating.

When used at the very beginning of your source code (before .model), the .386 directive does two (not just one!) things. Not only does it allow you to use the extra 80386 instructions in your source code, but it also changes the default segment type to USE32. And the problem is that you don't want to use code from a USE32 segment accessing data in a USE32 segment as your boot code.

One of the correct methods is to put .model (fixing the default segment type to USE16) before .386.

Under DEBUG, you can use the unassemble (U) command to see what kind of code the processor will execute in real mode.

=====

To get an idea of what may be happening, let's start with code that is assembled in a USE32 code segment BY MISTAKE.

66 89 CB  mov bx,cx

Notice the operand size prefix code 66. To get the exact same binary code in a USE16 code segment, you write

66 89 CB mov ebx,ecx

When you boot up, the processor itself is a full 386, Pentium or whatever and can execute this code, but assumes the code was assembled as USE16 code. If you wanted to leave the upper 16 bits of EBX unchanged, it won't happen.

You also get nasty effects where the processor uses 32-bit immediate data when you expected it to use 16-bit immediate data, effectively swallowing up instructions as Gustav illustrated. Or worse, the processor uses 16-bit addresses when 32-bit addresses were generated, adding two bytes of instruction code into the execution stream.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8