The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: hywum on December 17, 2011, 02:49:40 PM

Title: Use of bios interrupts
Post by: hywum on December 17, 2011, 02:49:40 PM
Hi,
first of all I want to tell you that I'm a beginner of programming in assembler and as you probably have found out yet, I'm german  :bg *I'm sorry for my Englisch*
I read that this code will wait for a keypress and show a messagebox.

.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
test db 'text!', 0

.code
start:
    mov ah, 0
    int 16h
    invoke MessageBox, NULL, addr test, addr test, MB_OK
    invoke ExitProcess, 0
end start

I think this is wrong and you have to use interrupts an other way.
Thanks for your replies and don't be too strict with me  :bg
Title: Re: Use of bios interrupts
Post by: dedndave on December 17, 2011, 03:33:18 PM
welcome to the forum   :U
bios interrupts are not usable in win32

the best routines for the any-key function are in the MS Visual C RunTime library (MSVCRT)
the actual MSVCRT functions are called crt__kbhit and crt__getch, in masm32
they are implemented for you in the masm 32-package with the "inkey" macro
keyboard input of this type is strictly a CONSOLE mode thing
so - assemble as a console app
start:
    inkey
    invoke MessageBox, NULL, addr test, addr test, MB_OK
    invoke ExitProcess, 0
Title: Re: Use of bios interrupts
Post by: dedndave on December 17, 2011, 03:37:17 PM
recently, i wanted to try one without using the MSVCRT
again - this is strictly a console thing   :P
;******************************************************************************

AnyKey  PROC

;Wait for Any Console Key Press - DednDave 12-2011
;
;  This function returns when any console key is pressed (bKeyDown = 1).
;A possible drawback is that all input event records are removed from
;the console input queue until a key is pressed. In many cases, this is
;not an issue. The virtual key code, virtual scan code, TCHAR character,
;and control key state values are returned in registers.

;Call With: Nothing
;
;  Returns: EAX = TCHAR character (high word of EAX = 0)
;           ECX = control key state flags
;               Bit   Name                Meaning
;                0    RIGHT_ALT_PRESSED   Right ALT key is pressed
;                1    LEFT_ALT_PRESSED    Left ALT key is pressed
;                2    RIGHT_CTRL_PRESSED  Right CTRL key is pressed
;                3    LEFT_CTRL_PRESSED   Left CTRL key is pressed
;                4    SHIFT_PRESSED       SHIFT key is pressed
;                5    NUMLOCK_ON          NUM LOCK light is on
;                6    SCROLLLOCK_ON       SCROLL LOCK light is on
;                7    CAPSLOCK_ON         CAPS LOCK light is on
;                8    ENHANCED_KEY        Key is enhanced
;           EDX:
;           low word (DX) = virtual key code
;               high word = virtual scan code
;
;           all other registers are preserved

        push    ebx
        push    ebp
        sub     esp,(sizeof INPUT_RECORD+3) and -4
        mov     ebp,esp
        INVOKE  GetStdHandle,STD_INPUT_HANDLE
        xchg    eax,ebx
        push    ecx

AnyKy0: INVOKE  ReadConsoleInput,ebx,ebp,1,esp
        movzx   edx,word ptr [ebp].INPUT_RECORD.EventType
        cmp     edx,KEY_EVENT                             ;KEY_EVENT EQU 1
        jnz     AnyKy0

        cmp     edx,[ebp].INPUT_RECORD.KeyEvent.bKeyDown
        jnz     AnyKy0

        pop     ecx
        movzx   eax,word ptr [ebp].INPUT_RECORD.KeyEvent.UnicodeChar
        mov     edx,dword ptr [ebp].INPUT_RECORD.KeyEvent.wVirtualKeyCode
        mov     ecx,[ebp].INPUT_RECORD.KeyEvent.dwControlKeyState
        add     esp,(sizeof INPUT_RECORD+3) and -4
        pop     ebp
        pop     ebx
        ret

AnyKey  ENDP

;******************************************************************************
Title: Re: Use of bios interrupts
Post by: hywum on December 17, 2011, 03:44:50 PM
Thanks a lot for your reply. Will my code work if I use a 16bit linker?
I'm gonna read your code later and ask some questions.
Title: Re: Use of bios interrupts
Post by: BogdanOntanu on December 17, 2011, 03:52:50 PM
Quote from: hywum on December 17, 2011, 03:44:50 PM
Thanks a lot for your reply. Will my code work if I use a 16bit linker?
I'm gonna read your code later and ask some questions.

No it will not work. 16 bits linker is useful only if you intend to write old 16 bits DOS applications. For Win32 or Win64 applications it is of no use.

You are mixing 16 bits INTs like int 16h and Win32 API's like MessageBox and ExitProcess in your code.... and this is bound to fail ;)

Make up your mind and decide what kind of code you want to write: 16 bits BIOS/DOS or 32 bits Win32 or 64bits Win64 eventually
Title: Re: Use of bios interrupts
Post by: dedndave on December 17, 2011, 04:15:48 PM
yah - you can write a 16-bit program (using a 16-bit linker), but it cannot have a message box   :'(

    mov ah, 0
    int 16h

that code will return when a key is pressed, but it will not remove it from the keyboard buffer
it is usually followed by code that does...
    mov ah, 0
    int 16h
    mov ah, 1
    int 16h


i strongly suggest you learn 32-bit code
16-bit is becoming obsolete fast - many members will say it already is - lol
Title: Re: Use of bios interrupts
Post by: hywum on December 17, 2011, 05:40:42 PM
I see. Why should I learn 32 bit programming in assembler?! I'm can program it with C++; this is much easier and I get the sam result, right?
But 16 bit programming is interesting. I read hat I can use it with every computer if I use only BIOS interrupts, or can I only use it with MS DOS?
Anyway thanks for your replies.  :)
Title: Re: Use of bios interrupts
Post by: jj2007 on December 17, 2011, 06:33:33 PM
Quote from: hywum on December 17, 2011, 02:49:40 PM
I'm german  :bg

Don't apologise, you are not the only one here...

Here is a simple DOS example showing how to print a number and wait for a keypress. If you prefer "true" assembler, look into the attached include file to see how it's done.

include \masm32\MasmBasic\Mb16.inc    ; inspired by DednDave (http://www.masm32.com/board/index.php?topic=12621.msg97236#msg97236)
  Init
  mov dx, Chr$("DOS is fun", 13, 10, "isn't it?")   ; display the
  mov ah, 9      ; message the
  int 21h         ; traditional way
  mov cx, Chr$(13, 10, "More fun")   ; display the message
  Print cx, 13, 10   ; using the cx register
  Print "Real fun", 13, 10   ; the simplest option
  Print Str$(123), " is 123", 13, 10   ; even that one works - Str$ takes immediates, ax, al, ah, si, ...
  Print cx, " again", 13, 10   ; Print and Str$ do not trash cx
  Inkey "bye"      ; wait for a key
  Exit         ; ExitProcess, DOS style
end start

OPT_Linker link16         
OPT_Assembler   Jwasm      ; JWasm (http://www.japheth.de/JWasm.html)
OPT_DebugA   /omf      ; use the /omf switch for ml 6.15 or higher
OPT_DebugA   /c      ; use the /c switch for ml version 6.14 (supplied with Masm32)


Re "it's easier in C": We are very tolerant here, and masochism is an accepted orientation :green
Title: Re: Use of bios interrupts
Post by: Magnum on December 17, 2011, 06:51:47 PM
hywum,

It really is worth learning assembly.

Most of the time, a C program is about 50 times the size of an assembly program.

I always wondered, "What else is that C program doing that makes it so big ?"  :P
Title: Re: Use of bios interrupts
Post by: zemtex on December 17, 2011, 07:06:12 PM
It is easy math:

1: Computer hardware will improve, fast, faster and even at insane speeds.
2: Developer teams compete of which can do the best programs and games.
3: Because of the second point, they will squeeze all hardware to maximum.
4: Because software will always squeeze hardware to maximum, assembly will always be relevant
5: If a c++ program can utilize X amount of force (while working at peak potential), asm can utilize X + 3

so asm will always be relevant, speed-wise

There are 2 things I fear.

1: RISC instruction sets.
2: The incredible amount of new annoying layers and renovations by microsoft which makes it hard to see a good future.

About the first point, it seems like we are getting more and more instruction sets every year, it just keeps flowing in, and this is a good thing for asm, because compilers will have more difficulties finding the best of everything as this monster grows.

Another scary thing is die size, it is shrinking fast and this will allow to put more instruction sets on the chip. It will not be very pleasant to use 10,000 instructions for an assembly programmer in 2020  :lol
Title: Re: Use of bios interrupts
Post by: hywum on December 17, 2011, 07:18:30 PM
Well, I think you're right and I should learn 32 bit ams programming and in about 200 years I will learn 16 bit programming when I'm able to program my own OS, but I think I won't live this long time.  :bg
Thanks a lot for your replies!
Title: Re: Use of bios interrupts
Post by: zemtex on December 17, 2011, 07:24:45 PM
Quote from: Magnum on December 17, 2011, 06:51:47 PM
hywum,

It really is worth learning assembly.

Most of the time, a C program is about 50 times the size of an assembly program.

I always wondered, "What else is that C program doing that makes it so big ?"  :P

A c++ programmer once told me that the reason asm programs are so small is because they lack much of the exception handling code that c++ has. I responded to him and said that, this exception handling code is contained in c++ wrappers and is irrelevant for an asm programmer. The OS already returns 0 on all functions if it fails, an assembly programmers doesn't need more than that.

Then he had it going, saying that C++ is the best language, I replied to him and said that C++ is not a computer language, it is a pseudo language. A language between the programmer and the guy who wrote the compiler.

Then he told me asm is not portable and I replied to him, C++ is not a portable computer language either. The reason C++ is portable is because it isn't a computer language to begin with and it has nothing to do with computers at all. You could basically port c++ to the moon, it is portable in that sense too, but it isn't a portable computer language.  :lol
Title: Re: Use of bios interrupts
Post by: Vortex on December 18, 2011, 01:51:43 PM
Quote from: Magnum on December 17, 2011, 06:51:47 PM
I always wondered, "What else is that C program doing that makes it so big ?"  :P

Another reason is the C run-time library. Turn it off, write your own and you will see that the size of C executables can be reduced.
Title: Re: Use of bios interrupts
Post by: Magnum on December 18, 2011, 04:36:58 PM
That's interesting gentlemen.