Is there a way to recognize when a key is pressed in 32-bit masm? I know you can use interrupts in 16 bit, but how can this be done using 32-bit, since 32-bit is protected by the OS.

Thanks,

Tyler S. Breton

Is there a way to recognize when a key is pressed in 32-bit masm? I know you can use interrupts in 16 bit, but how can this be done using 32-bit, since 32-bit is protected by the OS.

Thanks,

Tyler S. Breton

I haven't use these functions in assembly language. You might try the functions in a short C program until you figure out how they are used before using them in an assembly program.

There is nothing intrinsically protected about 32 bit code - it all depends upon the OS. You can still call interrupts like int 16h or int 21h, but you cannot then call Windows functions at the same time; it has to be one or the other.

In command line operating systems like MS-DOS a program can arrange things so that it only has to process keyboard input when it graciously invites the user to type something in response to an 1nt 16h or int 21h call. It is true that the user can type ahead to a limited extent, but if he thereby fills up the type ahead buffer that's tough on him.

In a GUI operating system like Windows there is no exact equivalent to the int 16h function, because the operating system tells your program when the user has struck a key (by sending it a "message"), and thereby invites your program to do something about it (like process the key code which Windows passed to it along with the message).

If you want to you can write that sort of program in assembly language (if you first read up on how Windows does things), but is more usual to write it in C (because there is no good reason for resorting to a lower level language).

>but how can this be done using 32-bit, since 32-bit is protected by the OS.
Access that functionality through the Win32 API, just like everyone else. It's trivial with MASM (as trivial as anything in assembly can be) because the assembler is written with Win32 applications in mind. Check your help files for example code. :)

>but how can this be done using 32-bit, since 32-bit is protected by the OS.
Access that functionality through the Win32 API, just like everyone else. It's trivial with MASM (as trivial as anything in assembly can be) because the assembler is written with Win32 applications in mind. Check your help files for example code. :)

An assembler can in principle by its very nature produce code for whatever operating system you care to name. When you compile a program in a high level language the compiler will be inserting a large number of calls to whatever OS it is compiling for. If it is compiled for Windows, and you try to run it under Linux, you will obviously have problems.

But when you are writing in assembler it is you who gets to decide what calls are made to which operating system, so if you want to write an MS-DOS program, which nevertheless makes use of 32 bit registers, and 32 bit variables, you can do it. If you try to run an MS-DOS program under Windows, Windows will switch the processor into what is known as Virtual 8086 mode, and the MS-DOS app will find itself sitting in what seems to it to be an MS-DOS machine, with 1mb of memory, the video buffer just where it expects to find it, an interrupt table sitting in the bottom 4kb of memory, and able to all the naughty things MS-DOS programs used to do.

I's a pure optical illusion of course, but a convincing one.

You will need to use a linker option, so that the header of the EXE file it produces is one for MS-DOS rather than Windows.

>An assembler can in principle by its very nature produce code for
>whatever operating system you care to name.
I think you're confused. An assembler produces machine code for the operating system that it's written for. That machine code is non-portable by nature due to varying expectations from the OS, such as object formats. Just because an assembler has builds for multiple operating systems doesn't mean that the machine code produced is portable in any way.

>When you compile a program in a high level language the compiler will be
>inserting a large number of calls to whatever OS it is compiling for.
And when you assemble a program in assembly, you make those calls yourself. The difference in portability between operating systems with assembly and higher level languages is minimal. I don't care if you want to talk about API calls or interrupts. Different systems have different system calls.

But when you are writing in assembler it is you who gets to decide what calls are made to which operating system, so if you want to write an MS-DOS program, which nevertheless makes use of 32 bit registers, and 32 bit variables, you can do it. If you try to run an MS-DOS program under Windows, Windows will switch the processor into what is known as Virtual 8086 mode, and the MS-DOS app will find itself sitting in what seems to it to be an MS-DOS machine, with 1mb of memory, the video buffer just where it expects to find it, an interrupt table sitting in the bottom 4kb of memory, and able to all the naughty things MS-DOS programs used to do.

I's a pure optical illusion of course, but a convincing one.

I fail to see your point. Windows provides backward compatibility? Okay, how does that change the fact that Win32 API calls are recommended over trying to live in the past with interrupts?

An assembler produces machine code for the machine (i.e. processor) not the operating system.

The difference between an assembler and compiler is that there is a direct one to one correspondence between assembly language instructions and machine code instructions, whereas a line of code in a high level language could correspond to a whole subroutine in machine code. Therefore you will not get any calls being made to the operating system in an assembly language program unless you explicitly put them in, and, without calls to the operating system, the code is as portable as could be wished for OS wise.

How do you think the operating system itself gets written, if assembly language is operating system dependent?

>An assembler produces machine code for the machine (i.e. processor) not the operating system.
Correct, but that doesn't make the machine code portable because it relies on knowledge of the operating system that it's assembled on. It very likely makes system calls that are not portable. It's required to match object file formats if the machine code is to be executable. Just because "in theory" portable machine code for a processor can be produced with some mythical universal assembler, it doesn't mean that the real world works that way.

The difference between an assembler and compiler is that there is a direct one to one correspondence between assembly language instructions and machine code instructions, whereas a line of code in a high level language could correspond to a whole subroutine in machine code.

I take it you're not familiar with macro assembly then. The one-to-one dealie hasn't logically applied in a long time. Sure, after macro expansion it's one-to-one, but that step is usually a part of the assembly and nobody sees it.

>without calls to the operating system, the code is as portable as could be wished for OS wise.
The assembly code might be portable, the machine code cannot be. For example, you can assemble a COFF program on Windows and it won't work on Linux because the two systems use slightly different formats for COFF. You need to take the portable assembly and assemble it individually for each system to get machine code that will work correctly.

>How do you think the operating system itself gets written, if assembly language is operating system dependent?
That question makes no sense at all. When the rules don't exist (such as writing the host itself), you can do anything. When the rules exist (such as writing a hosted program), you're bound by them.

>without calls to the operating system, the code is as portable as could be wished for OS wise.

The assembly code might be portable, the machine code cannot be. For example, you can assemble a COFF program on Windows and it won't work on Linux because the two systems use slightly different formats for COFF. You need to take the portable assembly and assemble it individually for each system to get machine code that will work correctly.

If were talking machine code as is, not the whole executable/object formats, the instruction set would stay portable assuming its run under the same processor architecture. However platform rules, enviroment and other specifics that will make things less compatible, my example would be the RDTSC instruction, one OS could allow this being executed in user mode while some other OS wouldn't as there is no calls made to the OS.

This article has been dead for over six months. Start a new discussion instead.