BetaArchive Logo
Navigation Home Screenshots Image Uploader Server Info FTP Servers Wiki Forum RSS Feed Rules Please Donate
UP: 30d, 4h, 31m | CPU: 52% | MEM: 6130MB of 11021MB used
{The community for beta collectors}

Forum rules


Any off topic discussions should go in this forum. Post count is not increased by posting here.
FTP Access status is required to post in this forum. Find out how to get it


Post new topic Reply to topic  [ 6 posts ] 
Author Message
 PostPost subject: Some assembler code        Posted: Fri Mar 07, 2008 12:37 am 
Reply with quote
Staff
User avatar
Offline

Joined
Wed Apr 11, 2007 2:11 pm

Posts
2607

Location
Germany, Earth

Favourite OS
Windows 10
Maybe someone here does know assembler. I want to know what this implies:

Code:
void VideoInit()
{
    __asm {
        mov     ax, 1202h;
        mov     bx, 0301h;
        int     10h;

        mov     ax, 3h;
        mov     bx, 0h;
        int     10h;

        mov     ax, 1112h;
        mov     bx, 0h;
        int     10h;

        mov     ax, 1003h;
        mov     bx, 0h;
        int     10h;

        mov     ax, 0200h;
        mov     bx, 0h;
        mov     dx, 0h;
        int     10h;
    }
    Cls();
}

_________________
MS vNext: Windows 10 ESD Database - Windows 10 Build Labs - Windows 10 Update Archive - Office 2016 Version Tracker - Office Downloader


Top  Profile  WWW
 PostPost subject:        Posted: Fri Mar 07, 2008 3:17 pm 
Reply with quote
Donator
Offline

Joined
Tue Oct 17, 2006 8:26 pm

Posts
932
Sure. It has been a while, so bare with me.

The first little block sets up the text mode to 400 scanlines. It is a little tricky to tell what it is doing because it is obfusicating the fact that it is putting 02H into the AH register, 12H into the AL register, 01H into the BH register and 03 into the BL register.

The second block is getting the cursor position and the size, on page 0.

The third block sets up the screen to 80x50 with a character width of 8.

The forth block sets up the video mode to VESA SVGA, version 2.


Top  Profile
 PostPost subject:        Posted: Fri Mar 07, 2008 3:25 pm 
Reply with quote
Staff
User avatar
Offline

Joined
Wed Apr 11, 2007 2:11 pm

Posts
2607

Location
Germany, Earth

Favourite OS
Windows 10
Thank you :)

_________________
MS vNext: Windows 10 ESD Database - Windows 10 Build Labs - Windows 10 Update Archive - Office 2016 Version Tracker - Office Downloader


Top  Profile  WWW
 PostPost subject:        Posted: Sat Mar 08, 2008 4:16 am 
Reply with quote
Donator
Offline

Joined
Sun May 13, 2007 12:42 am

Posts
2406
Is this from Singularity?


Top  Profile
 PostPost subject:        Posted: Sat Mar 08, 2008 3:10 pm 
Reply with quote
Staff
User avatar
Offline

Joined
Wed Apr 11, 2007 2:11 pm

Posts
2607

Location
Germany, Earth

Favourite OS
Windows 10
Windows OCManage wrote:
Is this from Singularity?


Yes it is. There are also comments in the source which are saying the same, but I asked because I couldn't believe that this piece of code does what it does - I have tried to understand assembler but It's too hard :oops:

_________________
MS vNext: Windows 10 ESD Database - Windows 10 Build Labs - Windows 10 Update Archive - Office 2016 Version Tracker - Office Downloader


Top  Profile  WWW
 PostPost subject:        Posted: Mon Mar 10, 2008 12:43 am 
Reply with quote
Donator
Offline

Joined
Tue Oct 17, 2006 8:26 pm

Posts
932
Actually, it is quite easy. To access system services (like BIOS, VESA, SCSI, etc), you use an interrupt call. If you are familiar with programming (not making any assumptions either way), an interrupt would be akin to a function call. The parameters for those functions are put into the CPU registers, main ones (called the General Purpose Registers) being AX, BX, CX, and DX. Now, these are the original 16-bit registers originating from way back in the 8086. A reference to these original registers is at: http://ourworld.compuserve.com/homepage ... oc_cpu.htm

Each of the 16-bit general purpose registers can be split into two usable 8-bit registers. For instance, AX can be broken up into AH and AL, for A(high byte) and A(low byte).

Also, here is a reference to interrupt 10 (which is being used in the code snippet posted): http://en.wikipedia.org/wiki/INT_10

Basically, you set up the parameters (move a value into the registers), and call the interrupt. It is that easy.

One of the things that makes this bit of code tricky to a newcomer is the fact that two important values are being moved into, say, the AX register with one move statement... let me elaborate:

Lets take the first block of code:
Code:
mov ax, 1202h;
mov bx, 0301h;
int  10h;


The first line is really moving 02h into AH and 12h into AL. This might seem backwards to you, because logic would tell you that 12 comes first, it should be going into the AH register. Actually, most processors now operate in what is called "little endian" mode. What this really means is that the bytes are stored backwards to how you normally read a number on paper. More details can be found here: http://en.wikipedia.org/wiki/Endianness#Little-endian

Ok, so anyway, 02h is being moved into AH and 12h is being moved into AL. Now take a look at the wikipedia page I linked to above and take a look at the third row in the table on that page, with the first column reading "Set cursor position".

You will notice, setting the cursor position involves moving 02h into AH, where whatever value is in BH is the page number. The second line takes care of this, by moving 01h into BH and 03h into BL. since BH is 01h, this means set cursor position to the first page.

Now with those three lines of code, there is already some problems with it. The first line moves 12h into AL, and the second line moves 03h into BL. Neither of these values do anything. They have no purpose, they will be ignored.

Also, you will notice in the documentation, that setting the cursor position also requires values in in DH to be the row the cursor gets moved to and DL is to be the column the cursor gets moved to. Neither of these are set, so essentially, even if the cursor makes it back to page 1 (if the values in DL and DL are invalid, the call to int 10 will fail), it will be in a completely random place. Now, there could be code before VideoInit to initialize the registers to sane values, but there is no way to know from this function, so it is bad practice to assume so.

The first block SHOULD be rewritten to:

Code:
mov ah, 02h;
mov bh, 01h;
mov dx, 0101h;
int  10h;


The rest of the code is just as sloppy. Even the function VideoInit is declared void, so there is no way to return a value to let the caller know that it failed. So more or less, if for whatever reason this function blows up (maybe you are trying to run on a machine without VESA 2.0 support), the whole system crashes, where a better solution would be to try and fall back to some other video mode, or even output to the serial port.


Top  Profile
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 




Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  

All views expressed in these forums are those of the author and do not necessarily represent the views of the BetaArchive site owner.

Powered by phpBB® Forum Software © phpBB Group

Copyright © 2006-2018

 

Sitemap | XML | RSS