Hello, I wonder why this program of mine doesn't work?
http://en.wikipedia.org/wiki/BIOS_interrupt_call - this is my reference. It should print out "!" but it just crashes.

bits 32
global _main

section .data


section .text
_main:
pushad ;preserve

mov ah, 0x0e
mov al, '!'
int 0x10

popad ;restore
ret


I tried this too:
bits 32
global _main

section .data


section .text
_main:
pushad ;preserve

mov al, 0x0D
mov ah, 0eh
    xor bh, bh
    int 10h
    ret

popad ;restore
ret


but it stil crashes. What am i doing wrong?
Posted on 2010-11-30 14:04:19 by pk0321
You are attempting to execute your code in a protected mode OS environment.  You may as well forget about trying to use any BIOS functions in 32/64-bit pmode - the OS won't let you.  If you're trying to write directly to video might I suggest learning DirectX or OpenGL.
Posted on 2010-11-30 17:39:33 by p1ranha
Change it to "bits 16" instead, it works for me. BIOS interrupts (like 0x10) don't exist in 32/64 bit pmode.
Posted on 2010-11-30 21:41:27 by clone4crw
Also tried with "bits 16" but it still crashes  :(

p1ranha, no i'm not trying to do anything with graphics, I just want to print out a couple of characters using BIOS interrupt instead of C printf function..
Posted on 2010-12-01 08:17:06 by pk0321
You don't indicate how this is being linked.
Posted on 2010-12-01 10:55:49 by SpooK
Or not linked... "bits 16" in conjunction with "nasm -f bin -o myfile.com myfile.asm" will produce a .com file which should run... IF your OS will support it - Win64 will not! I think "all" Win32 versions will(?).

Your problem is that "int 10h" (and all bios interrupts) are 16-bit code. Telling Nasm "bits 16" or "bits 32" (or "bits 64") does not affect what mode your CPU is running in, but simply tells Nasm which kind of code to produce. The CPU had "better" be running in the appropriate mode when it encounters this code!

If you need an alternative to "printf" in 32-bit code, look into the Windows API "WriteFile"...

Best,
Frank

Posted on 2010-12-02 13:09:21 by fbkotler
Your problem is that "int 10h" (and all bios interrupts) are 16-bit code.


int instruction has nothing to do with bitness (well, directly ;)). It's more like "do we have proper handler for it" question. In protected mode (except, probably, Virtual-8086 submode) the answer is mostly "No".

----8<----
Most flavors of Windows come with MSVCRT.DLL, which exports almost anything one may need from C RTL. ;)
Posted on 2010-12-03 05:48:26 by baldr
So, if I understand correctly, there is no way I can make these kind of interrupts working?

I hate to post the task but in this case I think this could help us to understand.

In assembly language, write function "upper" that converts a string to uppercase. Use the dedicated instructions and registers. To read and write call interrupts using instruction int (e.g. int 10h).


The first part I have already done. But it's the bold text that frustrates me. Currently I am printing out with _printf. Obviously this int 10h should work because if it wasn't it probably wouldn't be contained in this task..
Posted on 2010-12-05 04:02:03 by pk0321

Or not linked... "bits 16" in conjunction with "nasm -f bin -o myfile.com myfile.asm" will produce a .com file which should run... IF your OS will support it - Win64 will not! I think "all" Win32 versions will(?).



So what's your OS?

Best,
Frank

Posted on 2010-12-05 04:59:42 by fbkotler
I have Windows (7). In linux I also found you can do like this:

        word db "example",10,0   ; string
SIZE equ $-word            ; word size (bytes)

        mov    edx, SIZE
        mov    ecx, word
        mov    ebx, 1
        mov    eax, 4
        int        80h


but I tried it and i guess it doesn't work in windows..
Posted on 2010-12-05 09:11:01 by pk0321

Calls to int 80h are Linux specific and not the way things get done under Windows...
Posted on 2010-12-05 09:23:10 by p1ranha
Ok, so can you please tell me how to do it under Windows?

edit:
"bits 16" in conjunction with "nasm -f bin -o myfile.com myfile.asm"
does not work for first post code (it doesn't print out "!")..
Posted on 2010-12-05 09:31:28 by pk0321
System call interrupt per-OS










Interrupt    Target
0x10BIOS
0x21PC/DOS
0x2EPC/Windows
0x80UNIX


How you use each of these system calls is an independent subject all together. For example, 0x2E might change from build to build whereas the only time the 0x80 handlers have changed is between 32-bit and 64-bit.

Now, since we know that 0x2E can't actually be trusted across multiple builds, there needs to be a solution... Oh! So THAT'S what DLL's are for! (end of sarcasm)

The WIndows API is a whole set of DLL's which provide functionality of the operating system without actually having to worry about if things have changed from build to build. Microsoft implements it as part of their OS, they use it in their own applications, and there is really no major performance hit from you using it.

Now, as far as what frank was talking about with '-f bin', try using that same command with:

; build with: nasm -f bin dos.com dos.asm



_main:
;; we don't need to save registers, ax is going to be trashed anyway
; pushad
;; Here we invoke our INT 0x10
mov al, '!'
mov ah, 0x0E
int 0x10
; popad

;; We have to return something to DOS
xor ax, ax ; AL( Error Level ) - in this case zero.
mov ah, 0x4C ; AH( 4CH ) - System call for "Exit To DOS"
int 0x21


Again, as always with my code disclaimers (I don't run DOS, so this is totally untested code but it built none the less)
Posted on 2010-12-05 14:58:17 by Synfire

Ok, so can you please tell me how to do it under Windows?


Use proper WinAPI calls. FormatMessage() can give you the message for WriteFile() or WriteConsole(). You may use MSVCRT.DLL too, if you're going to use printf().
Posted on 2010-12-05 14:59:47 by baldr
Okay, I'm not familiar with Windows 7, and don't know if it supports dos or not, so I googled around a bit. Apparently the answer is, "Yes, but not well." There's a "tip" about halfway down this page which might help... or not.

http://www.tomshardware.com/forum/1441-63-full-screen-mode-programs

Actually, printf is a good way to do it! Well, printf is kinda "overkill" for just printing a string - puts() would be simpler. But either way, I could run such a program on Linux, and someone running a Mac could, too! I could attempt to show you an "obsolete" way to do it for Windows using Nasm's "-f obj" and Alink, which has the advantage of not needing any ".inc" files. If you're going to do it "for Windows", you probably want to get some ".inc" and ".lib"(?) files, and learn to do it the "modern" way!

BUT... the assignment (the "specification" for the program) explicitly says to use int 10h!

I probably should have asked, "What OS is your instructor using?"! Apparently, something that supports dos! So... if the only problem with Windows 7 is "no full-screen mode", maybe we can work around that...


; nasm -f bin -o myfile.com myfile.asm

bits 16 ; Nasm's default in "-f bin" mode

org 0x100 ; where dos will load us

section .text  ; also Nasm's default

; we don't need a "start" or "main" label for a .com file,
; it starts at the top of the file.

  mov al, '!'
  mov ah, 0xE
  mov bx, 7  ; "probably" not necessary
  int 0x10

  mov ah, 0
  int 0x16  ; wait for a key - hold the window open so we can see it!

  mov ax, 0x4C00  ; exit to dos, exitcode 0
  int 0x21


That's untested, but I think it's rite. :)

If that doesn't solve it, you could install "dosbox" - http://www.dosbox.com - or do it "for Windows" (but doesn't fulfill the specification!). If you've got it working with printf, that's "just as good"... or better! But I think you're "supposed" to do it with int 0x10!

Best,
Frank

Posted on 2010-12-05 19:01:07 by fbkotler