Thread: Assembly Tutorials

  1. #1
    Join Date
    Mar 2005

    Assembly Tutorials

    Anyone found some great assembly tutorials? I really want to learn assembly, thinking of making my own OS in the future, or building on an existing one so assembly would really help.


  2. #2
    Super Moderator
    Join Date
    Sep 2001
    As someone who has worked on his own OS before, I would give you the following little tidbit of information: The only part of an OS that has to be in assembly is the very small boot loader - and unless you want to write your own file system too (quite difficult), there are already boot loaders written for you. I have an example for FAT 12 if you want to take a look at it.

    The kernel and everything else could be (and often is) written in C/C++ if you wanted. Granted, you wouldn't be able to use the standard libraries, but it saves you a lot of trouble from assembly. You'd write some simple i/o routines in assembly, make them functions, and you'd be all set.

    I was making a server OS, and the reason I stopped is because of the device drivers I would need. It's a fun project and you learn a lot, but just be aware that this is a much bigger project than you may think.

    As for a tutorial, I'm afraid I can't suggest one. I've mostly learned from books.

  3. #3
    Super Moderator
    Join Date
    Sep 2001
    Also - try Google. I know it's directory was a wealth of information for me when I was doing my OS.

  4. #4
    Join Date
    May 2005
    Pretty good free assembly book that focuses on Linux and uses AT&T syntax:

  5. #5
    Join Date
    Mar 2005
    Thanks guys, Ya I know it would be a lot of work, but its such a cool thing to do. And I will learn so much, It would probably take more than a year but I think it would be worth it.

  6. #6
    Join Date
    Mar 2005
    Yeah sean could you post your example for FAT 12. I just want to see whats involved, and how its structured. Thanks

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Art of Assembly perhaps.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  8. #8
    Join Date
    May 2004
    I also recommend Art of Assembly. It goes into detail about everything.

  9. #9
    Registered User
    Join Date
    Jul 2004
    I've worked on OSes (strictly speaking still working on one but other stuff has taken over in importance). But I can recommend quite a few good websites:- - The intel manuals from here are essential (especially volumes 2+3)

    And for a bootloader, I would use GRUB, it's easy to setup and allows loading of modules and gives some system information. This helps alot when starting and even once the OS is finished, having it load a few modules helps, as then no drivers have to be physically loaded into the kernel (could still run at ring0 if you wanted monolithic - although no a great idea). You'll probably find that its best off just playing around with code to begin with (especially the OSD kernels above), but before you make a stab at a kernel which'll be any good, you'll really have to plan stuff out

    Hope this helps


  10. #10
    Super Moderator
    Join Date
    Sep 2001
    Before I post this, I should clarify that this is NOT my work - it was an example given in a tutorial on making operating systems. I'll try and find the site for you, but for now, this is the code:
    ;the ultimate boot-strap loader
    ;to load a file from a DOS FAT12 floppy as the OS
    [BITS 16]
    [ORG 0x0000]
    jmp     START
         OEM_ID                db "QUASI-OS"
         BytesPerSector        dw 0x0200
         SectorsPerCluster     db 0x01
         ReservedSectors       dw 0x0001
         TotalFATs             db 0x02
         MaxRootEntries        dw 0x00E0
         TotalSectorsSmall     dw 0x0B40
         MediaDescriptor       db 0xF0
         SectorsPerFAT         dw 0x0009
         SectorsPerTrack       dw 0x0012
         NumHeads              dw 0x0002
         HiddenSectors         dd 0x00000000
         TotalSectorsLarge     dd 0x00000000
         DriveNumber           db 0x00
         Flags                 db 0x00
         Signature             db 0x29
         VolumeID              dd 0xFFFFFFFF
         VolumeLabel           db "QUASI  BOOT"
         SystemID              db "FAT12   "
         ; code located at 0000:7C00, adjust segment registers
              mov     ax, 0x07C0
              mov     ds, ax
              mov     es, ax
              mov     fs, ax
              mov     gs, ax
         ; create stack
              mov     ax, 0x0000
              mov     ss, ax
              mov     sp, 0xFFFF
         ; post message
              mov     si, msgLoading
              call    DisplayMessage
         ; compute size of root directory and store in cx
              xor     cx, cx
              xor     dx, dx
              mov     ax, 0x0020                          ; 32 byte directory entry
              mul     WORD [MaxRootEntries]               ; total size of directory
              div     WORD [BytesPerSector]               ; sectors used by directory
              xchg    ax, cx
         ; compute location of root directory and store in ax
              mov     al, BYTE [TotalFATs]                ; number of FATs
              mul     WORD [SectorsPerFAT]                ; sectors used by FATs
              add     ax, WORD [ReservedSectors]          ; adjust for bootsector
              mov     WORD [datasector], ax               ; base of root directory
              add     WORD [datasector], cx
         ; read root directory into memory (7C00:0200)
              mov     bx, 0x0200                          ; copy root dir above bootcode
              call    ReadSectors
         ; browse root directory for binary image
              mov     cx, WORD [MaxRootEntries]           ; load loop counter
              mov     di, 0x0200                          ; locate first root entry
              push    cx
              mov     cx, 0x000B                          ; eleven character name
              mov     si, ImageName                       ; image name to find
              push    di
         rep  cmpsb                                       ; test for entry match
              pop     di
              je      LOAD_FAT
              pop     cx
              add     di, 0x0020                          ; queue next directory entry
              loop    .LOOP
              jmp     FAILURE
         ; save starting cluster of boot image
              mov     si, msgCRLF
              call    DisplayMessage
              mov     dx, WORD [di + 0x001A]
              mov     WORD [cluster], dx                  ; files first cluster
         ; compute size of FAT and store in cx
              xor     ax, ax
              mov     al, BYTE [TotalFATs]                ; number of FATs
              mul     WORD [SectorsPerFAT]                ; sectors used by FATs
              mov     cx, ax
         ; compute location of FAT and store in ax
              mov     ax, WORD [ReservedSectors]          ; adjust for bootsector
         ; read FAT into memory (7C00:0200)
              mov     bx, 0x0200                          ; copy FAT above bootcode
              call    ReadSectors
         ; read image file into memory (0100:0000)
              mov     si, msgCRLF
              call    DisplayMessage
              mov     ax, 0x0100                          ; destination of image CS
              mov     es, ax
              mov     bx, 0x0000                          ; destination for image IP
              push    bx
              mov     ax, WORD [cluster]                  ; cluster to read
              pop     bx                                  ; buffer to read into
              call    ClusterLBA                          ; convert cluster to LBA
              xor     cx, cx
              mov     cl, BYTE [SectorsPerCluster]        ; sectors to read
              call    ReadSectors
              push    bx
         ; compute next cluster
              mov     ax, WORD [cluster]                  ; identify current cluster
              mov     cx, ax                              ; copy current cluster
              mov     dx, ax                              ; copy current cluster
              shr     dx, 0x0001                          ;
         ;divide by two
              add     cx, dx                              ; sum for (3/2)
              mov     bx, 0x0200                          ; location of FAT in memory
              add     bx, cx                              ; index into FAT
              mov     dx, WORD [bx]                       ; read two bytes from FAT
              test    ax, 0x0001
              jnz     .ODD_CLUSTER
              and     dx, 0000111111111111b               ; take low twelve bits
             jmp     .DONE
              shr     dx, 0x0004                          ; take high twelve bits
              mov     WORD [cluster], dx                  ; store new cluster
              cmp     dx, 0x0FF0                          ; test for end of file
              jb      LOAD_IMAGE
              mov     si, msgCRLF
              call    DisplayMessage
              push    WORD 0x0100
              push    WORD 0x0000
              mov     si, msgFailure
              call    DisplayMessage
              mov     ah, 0x00
              int     0x16                                ; await keypress
              int     0x19                                ; warm boot computer
         ; PROCEDURE DisplayMessage
         ; display ASCIIZ string at ds:si via BIOS
              lodsb                                       ; load next character
              or      al, al                              ; test for NUL character
              jz      .DONE
              mov     ah, 0x0E                            ; BIOS teletype
              mov     bh, 0x00                            ; display page 0
              mov     bl, 0x07                            ; text attribute
              int     0x10                                ; invoke BIOS
              jmp     DisplayMessage
         ; PROCEDURE ReadSectors
         ; reads cx sectors from disk starting at ax into
         ;memory location es:bx
              mov     di, 0x0005                          ; five retries for error
              push    ax
              push    bx
              push    cx
              call    LBACHS
              mov     ah, 0x02                            ; BIOS read sector
              mov     al, 0x01                            ; read one sector
              mov     ch, BYTE [absoluteTrack]            ; track
              mov     cl, BYTE [absoluteSector]           ; sector
              mov     dh, BYTE [absoluteHead]             ; head
              mov     dl, BYTE [DriveNumber]              ; drive
              int     0x13                                ; invoke BIOS
              jnc     .SUCCESS                            ; test for read error
              xor     ax, ax                              ; BIOS reset disk
              int     0x13                                ; invoke BIOS
              dec     di                                  ; decrement error counter
              pop     cx
              pop     bx
              pop     ax
              jnz     .SECTORLOOP                         ; attempt to read again
              int     0x18
              mov     si, msgProgress
              call    DisplayMessage
              pop     cx
              pop     bx
              pop     ax
              add     bx, WORD [BytesPerSector]           ; queue next buffer
              inc     ax                                  ; queue next sector
              loop    .MAIN                               ; read next sector
         ; PROCEDURE ClusterLBA
         ; convert FAT cluster into LBA addressing scheme
         ; LBA = (cluster - 2) * sectors per cluster
              sub     ax, 0x0002                          ; zero base cluster number
              xor     cx, cx
              mov     cl, BYTE [SectorsPerCluster]        ; convert byte to word
              mul     cx
              add     ax, WORD [datasector]               ; base data sector
         ; convert ax LBA addressing scheme to CHS addressing scheme
         ; absolute sector = (logical sector / sectors per track) + 1
         ; absolute head   = (logical sector / sectors per track) MOD number of heads
         ; absolute track  = logical sector / (sectors per track * number of heads)
              xor     dx, dx                              ; prepare dx:ax for operation
              div     WORD [SectorsPerTrack]              ; calculate
              inc     dl                                  ; adjust for sector 0
              mov     BYTE [absoluteSector], dl
              xor     dx, dx                              ; prepare dx:ax for operation
              div     WORD [NumHeads]                     ; calculate
              mov     BYTE [absoluteHead], dl
              mov     BYTE [absoluteTrack], al
         absoluteSector db 0x00
         absoluteHead   db 0x00
         absoluteTrack  db 0x00
         datasector  dw 0x0000
         cluster     dw 0x0000
         ImageName   db "KERNEL  BIN"
         msgLoading  db 0x0D, 0x0A, "Loading Boot Image ", 0x0D, 0x0A, 0x00
         msgCRLF     db 0x0D, 0x0A, 0x00
         msgProgress db ".", 0x00
         msgFailure  db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x00
              TIMES 510-($-$$) DB 0
              DW 0xAA55
    Again, I'll try and find the site this came from, as you'd learn a lot about the bootstrap from the rest of the tutorial. I also wrote a very simple ASM kernel that you could build off of - it has the basics of I/O done.

  11. #11
    Registered User
    Join Date
    Jul 2004
    Erm, that bootsector doesn't put you into protected mode. Although you could do this yourself, it makes it more difficult as very few C compilers will support 16bit mode AND 32bit so you'd have to add a second stage loaded.

    The bootsector I use is attached, it performs pretty much everything you could want. But you have to have the 2 files it tries to load on the disk otherwise it'll just hang (no space left for error message code). It'll load a flat binary to 0x100000, enable pmode, load the second file (a config file or whatever you want), get a map of the available memory from the bios (can't use bios functions once you're in pmode) - from a floppy, not tested on any hard drive.

    Also another suggestion, don't go in trying to write the OS in C++, cause you have to write a memory manager immediately to cope with the new and delete constructors... (think that's right - I never use C++ myself for anything)

    Last edited by Pete; 06-04-2005 at 08:59 AM. Reason: Forgot attachement

  12. #12
    Join Date
    Jul 2004
    Can I ask why you can't use the STL in programming the OS?
    To code is divine

  13. #13
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    because STL makes use of new and new relies on an operating system.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :-

  14. #14
    Registered User
    Join Date
    Aug 2003
    You could prabably get by creating your own STL allocators. Never tried to do that though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C to assembly interface
    By Roaring_Tiger in forum C Programming
    Replies: 4
    Last Post: 02-04-2005, 03:51 PM
  2. should update their tutorials.
    By PorkyChop in forum C++ Programming
    Replies: 17
    Last Post: 09-19-2004, 10:51 PM
  3. assembly language...the best tool for game programming?
    By silk.odyssey in forum Game Programming
    Replies: 50
    Last Post: 06-22-2004, 01:11 PM
  4. True ASM vs. Fake ASM ????
    By DavidP in forum A Brief History of
    Replies: 7
    Last Post: 04-02-2003, 04:28 AM
  5. C,C++,Perl,Java
    By brusli in forum C Programming
    Replies: 9
    Last Post: 12-31-2001, 03:35 AM