{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Courier New;}} {\*\generator Msftedit 5.41.15.1503;}\viewkind4\uc1\pard\lang3081\f0\fs20 ________________________________________________________________________________\par \par \tab Dex4u: An Introduction to Application Programming Structure\par \tab\tab\tab\tab By Solidus117\par ________________________________________________________________________________\par \par \tab Contents\par \par \tab 1.0 Introduction\par \tab 1.1 Pre-requisites\par \tab 1.2 Resources\par \par \tab 2.0 Overview\par \tab 2.1 Generalised Application Structure\par \tab 2.2 Full Source Listing\par \tab 2.3 Source Code Breakdown\par \tab 2.4 Conclusion\par \tab\par \tab 3.0 Appendix A:\tab\tab Updates and Change Log\par \tab 3.1 Appendix B:\tab\tab Author Information\par \par \tab 4.0 Index\par ________________________________________________________________________________\par \par 1.0 Introduction\par \par Dex4u is a 32-bit protected mode, single-tasking operating system implemented\par entirely in x86 assembly language. This operating system shares similar traits to\par Microsoft's Disk Operating System (MS-DOS), and includes access to VESA\par compliant graphics adaptors.\par \par This operating system is currently experimental (although relatively stable). As\par such, any damage incurred through using this OS is through your own use.\par \par \tab\tab\tab\tab\tab - - - - -\par \par 1.1 Pre-requisites\par \par It is assumed that you have a sound knowledge of assembly language, and that you\par are comfortable using Flat Assembler. All code in this document is in FASM.\par \par The software requirements of this guide is as follows:\par \tab o The Dex4u OS on a floppy diskette;\par \tab o 'DexFunctions.inc';\par \tab o Flat Assembler (See Resources);\par \tab o A host operating system such as Microsoft Windows or Linux;\par \par \tab\tab\tab\tab\tab - - - - -\par \par 1.2 Resources\par \par The following websites contain auxiliary information about Dex4u and Flat\par Assembler.\par \par \tab Dex4u:\par \tab\tab o http://www.dex4u.com \tab The home of Dex4u\par \tab\tab o http://dex.7.forumer.com \tab The Dex4u Message Board/Forum\par \tab\tab\par \tab Flat Assembler:\par \tab\tab o http://flatassembler.net \tab The home of FASM by T. Grysztar\par \tab\tab o http://board.flatassmebler.net The FASM Message Board/Forum\par \tab\tab\par ________________________________________________________________________________\par \par 2.0 Overview\par \par Dex4u is a single-tasking operating system. At the present time, there are not\par many system services (i.e. Networking) to worry about, so this guide shall take\par you through the basics of implementing a simple application that will fulfil\par the following requirements:\par \par \tab o Be able to read and write files located on the current drive (except\par \tab CD-ROM media);\par \tab o Be able to gather input from the user;\par \tab o Be able to write data to the terminal (80x50 character text mode).\par \tab\par Now that the introductions have concluded, lets move onto the basics.\par \par \tab\tab\tab\tab\tab - - - - -\par \par 2.1 Generalised Application Structure\par \par The general structure of an application consists of an application header, then\par generally initialised data, code, uninitialised data, then finally the required\par system code inclusions. Below is a general representation (do not assemble):\par \par \tab\tab ;;;;; Header ;;;;;\par \tab\tab use32\par \tab\tab org 0x200000\par \tab\tab jmp initialise\par \tab\tab db 'DEX1'\par \par \tab\tab ;;; Init. Data ;;;\par \tab\tab data1 db 'Hi!',0\par \tab\tab data2 db 13,0\par \par \tab\tab ;;;;;; Code ;;;;;;\par \tab\tab initialise:\par \tab\tab\tab \par \tab\tab ret\par \tab \par \tab\tab ;; Uninit. Data ;;\par \tab\tab data3 db ?\par \tab\tab data4: times 32 db ?\par \tab \par \tab\tab include "DexFunctions.inc"\par \tab \par First the header.\par \par We use 32bit code for applications, therefore we instruct the assembler to use\par 32bit code. We organise the binary to load into memory at 200000h, as the\par operating system is loaded under this value. The next instruction defines the\par point that the actual code section starts. The final element is a 4-byte string\par that indicates that this binary is in fact a Dex4u binary.\par \par The Initialised data section. Although not entirely necessary, it is good\par practise to put initialised data here. Executing data is not nice. Notice that\par the strings data1 and data2 have 0's appended. This is the string delimiter used\par for writing strings to the terminal output, but more on this later.\par \par Code. All application code should be situated here. The tag will\par be covered later. 'ret' indicates returning to the OS Shell.\par \par Uninitialised data is the last section and generally is so because this is where\par you will load files from disk, put strings and so forth. The inclusion of\par 'DexFunctions.inc' is necessary. We will come to this shortly.\par \par As a side note, Dex4u binaries use a flat executable model, so do not include\par directives that format output binaries to MZ, PE, COFF or ELF executables. But\par the final binary must have a '.dex' extension for it be recognised as a Dex4u\par binary.\par \par \tab\tab\tab\tab\tab - - - - -\par \par 2.2 Full Source Listing\par \par Below is a listing of the application we will dissect. Cut and Paste where it\par indicates, assemble, test it, then go and read the breakdown. Since this\par application opens files, you will require something to read. Any ASCII text file\par is fine. \par \par It assembles as indicated:\par \tab o "fasm my_app.asm my_app.dex"\par \tab\par Source:\par \par ;------------------------------ Cut Here --------------------------------------;\par \par \tab ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\par \tab ; my_app.asm - Learning Application ;\par \tab ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\par \tab macro newline\par \tab\{\par \tab\tab mov esi,newline_string\par \tab\tab call [PrintString]\par \tab\}\par \par \par \tab ;----------; Application Header ;-----------;\par \tab\tab use32\par \par \tab\tab org 0x200000\par \tab\tab jmp initialise\par \tab\tab db 'DEX1'\par \par \par \tab ;------------; Initialised Data ;-----------;\par \tab name_string db 'Filename: ',0\par \tab wait_string db 'Press any key to continue',0\par \tab string_1 db 'You have ',0\par \tab string_2 db ' MB of Total Memory!',0\par \tab string_3 db ' MB of Extended Memory!',0\par \tab string_4 db ' Conventional Memory!',0\par \tab newline_string db 13,0\par \tab buffer_offset dd 0\par \par \tab ;--------------; Code Section ;-------------;\par \tab initialise:\par \tab\tab mov ax,0x18\tab\tab\tab\tab\tab ; Setup the segment registers\par \tab\tab mov ds,ax\par \tab\tab mov es,ax\par \par \tab\tab mov edi,Functions \tab\tab\tab ; This is the interrupt we use\par \tab\tab mov ax,0x0A00 \tab\tab\tab ; to load 'DexFunction.inc' call\par \tab\tab int 0x40\tab\tab\tab\tab\tab\tab ; table of functions.\par \par \tab getuserinput:\par \tab\tab mov esi,name_string\tab\tab\tab\tab ; Get the address of the string\par \tab\tab call [PrintString] \tab ; then call the system functions\par \tab\tab call [GetUserInput] \tab ; Get input from the user\par \tab\tab newline \tab ; use the newline macro\par \par \tab xor ebx,ebx\par \tab @@:\par \tab\tab cmp ebx,4095\tab\tab\tab\tab\tab ; This section initialises the\par \tab\tab je openfile\tab\tab\tab\tab\tab ; data buffer to 0.\par \tab\tab mov [filebuffer+ebx],dword 0\tab\tab\tab ; That way we can use a print\par \tab\tab inc ebx\tab\tab\tab\tab\tab\tab ; string call.\par \tab\tab jmp @b\par \par \tab openfile:\par \tab\tab mov esi,edi \tab ; See the relevant breakdown\par \tab\tab mov edi,filebuffer\par \tab\tab call [FloppyfileLoad]\par \tab\tab mov ax,18\par \tab\tab call [SetDelay]\par \tab\tab jc quit_app\par \par \par \tab dumpbuffer:\par \tab\tab mov esi,filebuffer\tab\tab\tab\tab ; See relevant breakdown\par \tab\tab call [PrintString]\par \tab\tab newline\par \tab\tab mov esi,wait_string\par \tab\tab call [PrintString]\par \tab\tab call [WaitForKeyPress]\par \tab\tab newline\par \tab\tab newline\par \par \par \tab getmemory:\par \tab\tab call [ExtendedMemory]\par \tab\tab imul eax,1024\tab\tab\tab\tab\tab ; Convert to megabytes\par \tab\tab mov [extend_mem],eax\tab\tab\tab\tab ; Then put in memory\par \tab\tab call [ConvenMemorySize]\par \tab\tab imul eax,1024\par \par \tab printconv_memory:\par \tab\tab mov esi,string_1\par \tab\tab call [PrintString]\par \tab\tab call [WriteHex32]\tab\tab\tab\tab\tab ; Eax already has the conv.\par \tab\tab mov esi,string_4\par \tab\tab call [PrintString]\par \tab\tab newline\par \par \tab printext_memory:\par \tab\tab mov esi,string_1\par \tab\tab call [PrintString]\par \tab\tab mov eax,[extend_mem]\par \tab\tab call [WriteHex32]\par \tab\tab mov esi,string_3\par \tab\tab call [PrintString]\par \tab\tab newline\par \par \tab printtotal_memory:\par \tab\tab mov esi,string_1\par \tab\tab call [PrintString]\par \tab\tab mov eax,ebx\par \tab\tab call [WriteHex32]\par \tab\tab mov esi,string_2\par \tab\tab call [PrintString]\par \tab\tab newline\par \par \tab quit_app:\par \tab\tab newline\par \tab\tab mov esi,wait_string\par \tab\tab call [PrintString]\par \tab\tab call [WaitForKeyPress]\par \tab\tab ret\tab\tab\tab\tab\tab\tab\tab ; End application\par \par \par \par \tab ;-----------; Uninitialised Data ;----------;\par \tab filebuffer: times 4096 db ?\tab\tab\tab ; 4kb Buffer\par \tab extend_mem dd ?\par \par \tab include "DexFunctions.inc"\par \par ;------------------------------ Cut Here --------------------------------------;\par \par \tab\tab\tab\tab\tab - - - - -\par \par 2.3 Source Code Breakdown\par \par This is a pretty simple application. It simply does this:\par \tab o Gets a filename from the user;\par \tab o Reads a file of that filename into a 4 kilobyte buffer;\par \tab o Dumps the buffer to screen;\par \tab o Gets the Conventional, Extended and Total Memory and prints the\par \tab hexadecimal values to screen.\par \tab \par Now, there are a few inefficiencies and rough edges, but optimisations can be\par performed after learning. I have used address labels to label code stublets.\par \par Hopefully you are proficient in using macros, as the macro 'newline' simply\par does that, prints a newline. The application header should also look\par familiar, as this was covered previously under section 2.1.\par \par The 'Initialised Data' section of our application is straightforward, and is also\par discussed previously in section 2.1.\par \par Let's start with 'initialise'.\par \par \tab\tab mov ax,0x18\par \tab\tab mov ds,ax\par \tab\tab mov es,ax\par \par \tab\tab mov edi,Functions\par \tab\tab mov ax,0x0A00\par \tab\tab int 0x40\par \par Firstly, we initialise segment registers DS and ES with 18h. Then load EDI and\par ax with the function call table pointer and A00h respectively. This sets up the\par application to use the function call table, of which we use heavily.\par \par Next, we have to get a string from the user to use as a filename. Here we\par immediately use the string in the next stublet, but you could alternately copy\par the string into an uninitialised data buffer, using the value of cx to determine\par the amount of elements needed for such a buffer. We also print a 0 terminated\par string for prompting.\par \par \tab\tab mov esi,name_string\par \tab\tab call [PrintString]\par \tab\tab call [GetUserInput]\par \tab\tab newline\par \par As you can see, function calls are simply the case of loading the required\par registers with required data, the calling the actual name of the function.\par \par \tab\tab xor ebx,ebx\par \tab\tab @@:\par \tab\tab\tab cmp ebx,4095\par \tab\tab\tab je openfile\par \tab\tab\tab mov [filebuffer+ebx],dword 0\par \tab\tab\tab inc ebx\par \tab\tab\tab jmp @b\par \par This section is fairly simple, as all of the soon-to-be-used file buffer is\par zeroed. See the Flat Assembler documentation for more information about\par reserving data.\par \par \tab\tab mov esi,edi\par \tab\tab mov edi,filebuffer\par \tab\tab call [FloppyfileLoad]\par \tab\tab mov ax,18\par \tab\tab call [SetDelay]\par \tab\tab jc quit_app\par \par 'openfile' simply does that. The only point to be made is that on error, the\par carry flag is set. If this checked while the file is still reading off the\par drive, it will jump to 'quit_app'. Therefore we have to add a delay before we\par decide what to do. This is done with 'SetDelay'. See 'DexFunctions.inc' for more\par information.\par \par \tab\tab mov esi,filebuffer\par \tab\tab call [PrintString]\par \tab\tab newline\par \tab\tab mov esi,wait_string\par \tab\tab call [PrintString]\par \tab\tab call [WaitForKeyPress]\par \tab\tab newline\par \tab\tab newline\par \tab\tab\par We have already covered these functions. Basically, it's all about loading\par registers with values, then calling the appropriate function. We'll jump to\par 'quit_app'.\par \par \tab\tab newline\par \tab\tab mov esi,wait_string\par \tab\tab call [PrintString]\par \tab\tab call [WaitForKeyPress]\par \tab\tab ret\par \par What's to be said about 'quit_app'? Well, as soon as 'ret' is called, the\par application will return to the CLI. So be weary about calling your own functions\par then returning from them.\par \par \tab\tab\tab\tab\tab - - - - -\par \tab\par 2.4 Conclusion\par \par As mentioned before, an application consists of calls to functions, then moving\par the data around, and calling more functions. Simple. This is just a simple\par application and is by no means definitive of what Dex4u is capable of. Please\par investigate 'DexFunctions.inc' for more information on the necessary registers\par for different calls.\par \par ________________________________________________________________________________\par \par 3.0 Appendix A: Updates and Change Log\par \par 27 / 12 / 2005\par \par \tab\tab o Version 1.0 of this file.\par \par \tab\tab\tab\tab\tab - - - - -\par \tab\tab\tab\tab\tab\tab\tab\par 3.1 Appendix B: Author Information\par \par mail:\tab\tab\tab starfiredev@hotmail.com\par dex forums:\tab\tab solidus117\par homepage:\tab\tab http://mars.walagata.com/w/solidus117/main.html\par weblog:\tab\tab http://spaces.msn.com/members/collectivecyber\par \par ________________________________________________________________________________\par \par }