How to make a SOFTWARE.BIG with NASM

Reference picture of the post "How to make a SOFTWARE.BIG with NASM"

In this post, I write about how to make the SOFTWARE.BIG1 file with NASM, I experiment with the segmentation of RAM and I use the %include directive.

In the post "Getting a new tool", I wrote why I needed to extend my toolbox and I got NASM as a new tool which I planned to use together with DEBUG.EXE. In the two posts before this one, I wrote about what the directives ORG and SECTION are and how to use them. I also explained that the directive SECTION can be used to define segments. At this point, I have to show how to use this new tool (NASM) to make the SOFTWARE.BIG file and continue my exploration of the deep binary space. I thought that meanwhile creating a demonstrative SOFTWARE.BIG (just to demonstrate how to do it), I could also take this opportunity to experiment a little bit on two aspects:

Segments in RAM have no predefined purpose in 8086 real-mode

In 8086 16-bit real mode, every segment is a consecutive block of 64KB RAM. Just it. There is no additional constraint about being one of such segment read-only, or not executable and so on. The segments are just 64KB of RAM that the programmer can use as he/she wants. There is no concept of a code segment or a data segment. To demonstrate it I have created a program that defines seven segments with the use of the directive SECTION. I named the segments by colours to remark the fact that segments are free from labels but it is the use that the programmer makes of them that gives meaning to the segments.

The file: "Learn NASM - 03.asm"
;############################################################################## ; Learn NASM - 03.asm ; ; ; Build with: ; nasm -f bin "Learn NASM - 03.asm" -l "Learn NASM - 03.lst" -o "SOFTWARE.BIG" ;############################################################################## org 0x7c00 ; Loading point of SOFTWARE.BIG in RAM ; ;############################################################################## ; Full definition of section IN COMBINATION WITH -f bin !!! ; ; Sections can be aligned at a specified boundary following the previous ; section with align=, or at an arbitrary byte-granular position with start=. ; ; align= -> can be any power of 2. ; start= -> is a flat address (example: 0x01_7C00) where the section starts ; in memory. ; vstart= -> the virtual start address, which will be used for the calculation ; of all memory references within that section ;############################################################################## section _general_reset start=0x0_7c00 section _red start=0x0_7c30 vstart=0x00 section _blue start=0x1_7c30 vstart=0x00 section _green start=0x2_7c30 vstart=0x00 section _yellow start=0x3_7c30 vstart=0x00 section _pink start=0x4_7c30 vstart=0x00 section _orange start=0x5_7c30 vstart=0x00 ;############################################################################## ; General reset ; SHUTTLE2 leaves CS = DS = ES = SS = 0x0000 and I want to set: ; DS = _blue ; ES = _green ; SS = _orange ; CS = _red ;############################################################################## section _general_reset ;---------------------------------------- ; Validation signature for SOFTWARE.BIG ;---------------------------------------- DB 0xA2, 0xDD, 0x7B, 0x8B, 0x87, 0x00, 0x05, 0x3D, \ 0xFF, 0xFF, 0x74, 0x19, 0x3D, 0x02, 0x00, 0x72 cli ; deactivate interrupts mov ax, 0x17c3 ; DS = _blue mov ds, ax ; mov ax, 0x27c3 ; ES = _green mov es, ax ; mov ax, 0x57c3 ; SS = _orange mov ss, ax ; mov sp, 0xfffe ; sti ; reactivate interrupts jmp 0x07c3:_entry_point ; Jump _entry_point: ---> ;############################################################################## ; ; PROGRAM START ; ;############################################################################## section _red ; ; <--- ; _entry_point: mov si, _bbb ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _aaa ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ; ;-------------------------------------------------------------------------- ; wait for key press... ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character jmp 0x17c3:_nowBlue ; Jump _nowBlue: ---> section _blue ; ; <--- ; _nowBlue: mov si, _ccc ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _aaa ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ; ;-------------------------------------------------------------------------- ; wait for key press... ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character jmp 0x27c3:_nowGreen ; Jump _nowGreen: ---> section _green ; ; <--- ; _nowGreen: mov si, _ddd ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _aaa ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ; ;-------------------------------------------------------------------------- ; wait for key press... ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character jmp 0x37c3:_nowYellow ; Jump _nowYellow: ---> section _yellow ; ; <--- ; _nowYellow: mov si, _eee ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _aaa ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ; ;-------------------------------------------------------------------------- ; wait for key press... ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character jmp 0x47c3:_nowPink ; Jump _nowPink: ---> section _pink ; ; <--- ; _nowPink: mov si, _fff ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _aaa ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ; ;-------------------------------------------------------------------------- ; wait for key press... ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character jmp 0x57c3:_nowOrange ; Jump _nowOrange: ---> section _orange ; ; <--- ; _nowOrange: mov si, _ggg ; SI -> "CS =...". call 0x07c3:_SHOW_STR ; mov si, _hhh ; SI -> "Press any key for next jump...". call 0x07c3:_SHOW_STR ; ;-------------------------------------------------------------------------- ; wait for key press and terminate ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character ; jmp 0xffff:0000 ; Total system reset since INT19 hangs ; on HP Elitebook ;############################################################################## ; All messages in section _blue ;############################################################################## section _blue _aaa: db "Press any key for next jump...", 0x0d, 0x0a, 0x00 _bbb: db "CS = _red", 0x0d, 0x0a, 0x00 _ccc: db "CS = _blue", 0x0d, 0x0a, 0x00 _ddd: db "CS = _green", 0x0d, 0x0a, 0x00 _eee: db "CS = _yellow", 0x0d, 0x0a, 0x00 _fff: db "CS = _pink", 0x0d, 0x0a, 0x00 _ggg: db "CS = _orange", 0x0d, 0x0a, 0x00 _hhh: db "Press any key to reboot...", 0x0d, 0x0a, 0x00 ;############################################################################## ; ; SHOW_STR: SHOW STRing ; ; This procedure shows a string on the video starting at address [DS:SI] ; and terminating as soon as it finds the byte 0x00 ; ; INPUT: [DS:SI] at start of string (1st char) ; OUTPUT: [DS:SI] at end of string (char 0x00) ; REGISTER USAGE: AX, BX ; THIS ONE CALLS: int10 ; ;############################################################################## section _red _SHOW_STR: push ax ; Preserve extra used registers. push bx ; jmp _show_str_start ; JUMP _show_str_start: ---> ; ;<--- ; _one_char_on_screen: ; ;--------------------------------------- ; standard setup for displaying ; characters on the screen ;--------------------------------------- mov ah, 0x0e ; int10/ah = 0e : video teletype out ; al = character to write mov bx, 0x07 ; bh = page number ; bl = foreground color (graphics mode only) ; int10 returns nothing int 0x10 ; ; ;<--- ; _show_str_start: ; lodsb ; AL = [DS:SI]; SI = SI + 1 cmp al, 0x00 ; flags = AL - 0x00 ; Unsigned comparison: jne _one_char_on_screen ; JumpNotEqual _one_char_on_screen: ---> ; ;-------------------------------------------------------------------------- ; END of local procedure SHOW_STR ;-------------------------------------------------------------------------- pop bx ; Restore extra used registers. pop ax ; retf ;

I assigned the Stack Segment Register (SS) to _orange and the Data Segment Register (DS) to _blue, but this doesn't mean that the RAM segments _orange and _blue are just stack and data. In fact, I used all segments for code as well and I jumped from the first to the last segment every time executing a small portion of code. In this way, I showed that, for instance, the RAM segment _orange can be a Stack Segment and a Code Segment at the same time.

Another important aspect of this program was that I created a large SOFTWARE.BIG (about 321 KB) that my boot loader SHUTTLE2 had to load by scanning the FAT one cluster after the other hence this was also a test for my boot loader SHUTTLE2 at the same time.

I embedded the procedure SHOW_STR in the _red segment to bring the messages on the screen, but since the value of the CS segment had to change from jump to jump, I planned to use FAR CALL and FAR RETURN. The FAR CALL is realized with the syntax call seg:off and the FAR RETURN with the OPCODE retf. Please note that when using the option -f bin with NASM, the names of the sections are not labels! This means that call _red:_SHOW_STR is not legal and one has to use the numeric value of the segment defined with the SECTION directive like this: call 0x07c3:_SHOW_STR2.

Fig. A - Screenshot
Fig. A - Screenshot

In Fig. A you see the screenshot on my test notebook and this concludes this experiment.

How to use the %include directive with NASM.

The %include directive is used by the preprocessor of NASM. The preprocessor replaces all lines where the %include directive appears with the file that the same directive is pointing to. If the included file contains again a new %include directive, the preprocessor repeats the same process on and on again until all %include directives are properly replaced by the content of the file they are pointing to.
I wanted to take advantage of this functionality and I thought to organize my projects in the following way.

Fig. B - Organization of a SOFTWARE.BIG project
Fig. B - Organization of a SOFTWARE.BIG project

I created a main folder which contained the MAIN ASM-file of the project together with an INC-file and a subfolder with the same name as the MAIN ASM-file (see Fig. B). My idea was to use the MAIN ASM-file as the entry point of the project. The subfolder named following the MAIN ASM-file was the place to keep all the used service procedures. This was my way to organize the library for the project. Finally, I used the INC-file to list all the sub-procedure that the MAIN procedure needed and that were stored inside the library folder.

Here follows an example that I created to test this idea and illustrate it at the same time. Additionally, based on the experience made in the previous paragraph, I decided to use three segments only: _justCode, _justData and _justStack.

The file: "Learn NASM - 04.asm"
;############################################################################## ; "Learn NASM - 04.nsm" ; ; ; Build with: ; nasm -f bin "Learn NASM - 04.asm" -l "Learn NASM - 04.lst" -o "SOFTWARE.BIG" ;############################################################################## org 0x7c00 ; Loading point of SOFTWARE.BIG in RAM ; The function of the ORG directive is to specify ; the origin address which NASM will assume ; the program begins at when it is loaded ; into memory. Its sole function is to specify one ; offset which is added to all internal address ; references within the section (section) unless ; one redefine the section with a vstart= option. ; ; IMPORTANT!!! ; -> org can be used only one time in the whole ; source code. ; -> org can be placed anywhere in the source code ; (but only once). ; -> org can be used only with -f bin output file ; format (it is not the same as in MASM). ;############################################################################## ; Full definition of section IN COMBINATION WITH -f bin !!! ; ; IMPORTANT!!! ; In case of -f bin, section CAN BE USED to define a segment but IT IS NOT a ; synonymous for SEGMENT ; ; Sections can be aligned at a specified boundary following the previous ; section with align=, or at an arbitrary byte-granular position with start=. ; ; align= -> can be any power of 2. ; start= -> is a flat address (example: 0x01_7C00) where the section starts ; in memory. ; vstart= -> the virtual start address, which will be used for the calculation ; of all memory references within that section ;############################################################################## section _general_reset start=0x0_7c00 section _justCode start=0x0_7c30 vstart=0x00 section _justData start=0x1_7c30 vstart=0x00 section _justStack start=0x2_7c30 vstart=0x00 ;############################################################################## ; Include all required service procedures. ;############################################################################## %include ".\Learn NASM - 04.inc" ;############################################################################## ; General reset ; SHUTTLE2 leaves CS = DS = ES = SS = 0x0000 and I want to set: ; ES = DS = _justData ; SS = _justStack ; CS = _justCode ;############################################################################## section _general_reset ;---------------------------------------- ; Validation signature for SOFTWARE.BIG ;---------------------------------------- DB 0xA2, 0xDD, 0x7B, 0x8B, 0x87, 0x00, 0x05, 0x3D, \ 0xFF, 0xFF, 0x74, 0x19, 0x3D, 0x02, 0x00, 0x72 cli ; deactivate interrupts mov ax, 0x17c3 ; DS = _justData mov ds, ax ; mov es, ax ; mov ax, 0x27c3 ; SS = _justStack mov ss, ax ; mov sp, 0xfffe ; sti ; reactivate interrupts jmp 0x07c3:_entry_point ; Jump _entry_point: ---> ;############################################################################## ; ; PROGRAM START ; ;############################################################################## ;--------------------------------- ; Start chat ;--------------------------------- section _justData _aaa: db " Landing Module II:", 0x0d, 0x0a db " Hello Huston, we have a good landing.", 0x0d, 0x0a db 0x0d, 0x0a, 0x00 ; ; <--- ; section _justCode _entry_point: mov si, _aaa ; SI -> "Hello Huston...". call _SHOW_STR ; ; section _justData _bbb: db "Huston:", 0x0d, 0x0a db "God Job! We confirm from here that all systems are ok.", 0x0d, 0x0a db "You can close the mission. Thank you!", 0x0d, 0x0a, 0x0d, 0x0a, 0x00 section _justCode mov si, _bbb ; SI -> "God Job!...". call _SHOW_STR ; ; section _justData _ccc: db " Landing Module II:", 0x0d, 0x0a db " OK Huston, we shut down the systems", 0x0d, 0x0a db " and close the mission.", 0x0d, 0x0a, 0x00 section _justCode mov si, _ccc ; SI -> "OK Huston...". call _SHOW_STR ; ; ; ;-------------------------------------------------------------------------- ; wait for key press and terminate ;-------------------------------------------------------------------------- xor ax, ax ; int 16/ah = 00 : keyboard get keystroke int 0x16 ; returns: ah = BIOS scan code ; al = ASCII character ; jmp 0xffff:0000 ; Total system reset since INT 19H hangs ; on HP Elitebook


The file: "Learn NASM - 04.inc"
;############################################################################## ; INCLUDE file for "Learn NASM - 04.nsm" ; ; This file lists all required file that need to be included. ;############################################################################## %include ".\Learn NASM - 04\show_string.asm"

In the list file, you can see the effect of the repeated %include which had generated a huge, single text file that NASM assembled all together.

The file: "Learn NASM - 04.lst"
1 ;############################################################################## 2 ; "Learn NASM - 04.nsm" 3 ; 4 ; 5 ; Build with: 6 ; nasm -f bin "Learn NASM - 04.asm" -l "Learn NASM - 04.lst" -o "SOFTWARE.BIG" 7 ;############################################################################## 8 9 org 0x7c00 ; Loading point of SOFTWARE.BIG in RAM 10 ; The function of the ORG directive is to specify 11 ; the origin address which NASM will assume 12 ; the program begins at when it is loaded 13 ; into memory. Its sole function is to specify one 14 ; offset which is added to all internal address 15 ; references within the section (section) unless 16 ; one redefine the section with a vstart= option. 17 ; 18 ; IMPORTANT!!! 19 ; -> org can be used only one time in the whole 20 ; source code. 21 ; -> org can be placed anywhere in the source code 22 ; (but only once). 23 ; -> org can be used only with -f bin output file 24 ; format (it is not the same as in MASM). 25 26 27 ;############################################################################## 28 ; Full definition of section IN COMBINATION WITH -f bin !!! 29 ; 30 ; IMPORTANT!!! 31 ; In case of -f bin, section CAN BE USED to define a segment but IT IS NOT a 32 ; synonymous for SEGMENT 33 ; 34 ; Sections can be aligned at a specified boundary following the previous 35 ; section with align=, or at an arbitrary byte-granular position with start=. 36 ; 37 ; align= -> can be any power of 2. 38 ; start= -> is a flat address (example: 0x01_7C00) where the section starts 39 ; in memory. 40 ; vstart= -> the virtual start address, which will be used for the calculation 41 ; of all memory references within that section 42 ;############################################################################## 43 section _general_reset start=0x0_7c00 44 section _justCode start=0x0_7c30 vstart=0x00 45 section _justData start=0x1_7c30 vstart=0x00 46 section _justStack start=0x2_7c30 vstart=0x00 47 48 49 ;############################################################################## 50 ; Include all required service procedures. 51 ;############################################################################## 52 %include ".\Learn NASM - 04.inc" 53 <1> ;############################################################################## 54 <1> ; INCLUDE file for "Learn NASM - 04.nsm" 55 <1> ; 56 <1> ; This file lists all required file that need to be included. 57 <1> ;############################################################################## 58 <1> 59 <1> %include ".\Learn NASM - 04\show_string.asm" 60 <2> ;############################################################################## 61 <2> ; "show_string.asm" 62 <2> ; _SHOW_STR: SHOW STRing 63 <2> ; 64 <2> ; This procedure shows a string on the video starting at address [DS:SI] 65 <2> ; and terminating as soon as it finds the byte 0x00 66 <2> ; 67 <2> ; INPUT: [DS:SI] at start of string (1st char) 68 <2> ; OUTPUT: [DS:SI] at end of string (char 0x00) 69 <2> ; REGISTER USAGE: AX, BX 70 <2> ; THIS ONE CALLS: INT 10H 71 <2> ; 72 <2> ;############################################################################## 73 <2> ; 74 <2> ;<--- MAIN ENTRY POINT 75 <2> ; 76 <2> section _justCode 77 <2> _SHOW_STR: 78 00000000 50 <2> push ax ; Preserve extra used registers. 79 00000001 53 <2> push bx ; 80 00000002 EB07 <2> jmp _show_str_start ; JUMP _show_str_start: ---> 81 <2> 82 <2> ; 83 <2> ;<--- 84 <2> ; 85 <2> _one_char_on_screen: ; 86 <2> ;--------------------------------------- 87 <2> ; standard setup for displaying 88 <2> ; characters on the screen 89 <2> ;--------------------------------------- 90 00000004 B40E <2> mov ah, 0x0e ; int10/ah = 0e : video teletype out 91 <2> ; al = character to write 92 00000006 BB0700 <2> mov bx, 0x07 ; bh = page number 93 <2> ; bl = foreground color (graphics mode only) 94 <2> ; int10 returns nothing 95 00000009 CD10 <2> int 0x10 ; 96 <2> 97 <2> ; 98 <2> ;<--- 99 <2> ; 100 <2> _show_str_start: ; 101 0000000B AC <2> lodsb ; AL = [DS:SI]; SI = SI + 1 102 0000000C 3C00 <2> cmp al, 0x00 ; flags = AL - 0x00 103 <2> ; Unsigned comparison: 104 0000000E 75F4 <2> jne _one_char_on_screen ; JumpNotEqual _one_char_on_screen: ---> 105 <2> ; 106 <2> ;-------------------------------------------------------------------------- 107 <2> ; END of local procedure SHOW_STR 108 <2> ;-------------------------------------------------------------------------- 109 00000010 5B <2> pop bx ; Restore extra used registers. 110 00000011 58 <2> pop ax ; 111 00000012 C3 <2> ret ; 60 <1> 53 54 55 ;############################################################################## 56 ; General reset 57 ; SHUTTLE2 leaves CS = DS = ES = SS = 0x0000 and I want to set: 58 ; ES = DS = _justData 59 ; SS = _justStack 60 ; CS = _justCode 61 ;############################################################################## 62 section _general_reset 63 ;---------------------------------------- 64 ; Validation signature for SOFTWARE.BIG 65 ;---------------------------------------- 66 00000000 A2DD7B8B8700053DFF- DB 0xA2, 0xDD, 0x7B, 0x8B, 0x87, 0x00, 0x05, 0x3D, 0xFF, 0xFF, 0x74, 0x19, 0x3D, 0x02, 0x00, 0x72 66 00000009 FF74193D020072 68 69 00000010 FA cli ; deactivate interrupts 70 00000011 B8C317 mov ax, 0x17c3 ; DS = _justData 71 00000014 8ED8 mov ds, ax ; 72 00000016 8EC0 mov es, ax ; 73 00000018 B8C327 mov ax, 0x27c3 ; SS = _justStack 74 0000001B 8ED0 mov ss, ax ; 75 0000001D BCFEFF mov sp, 0xfffe ; 76 00000020 FB sti ; reactivate interrupts 77 00000021 EA[1300]C307 jmp 0x07c3:_entry_point ; Jump _entry_point: ---> 78 79 80 81 82 83 ;############################################################################## 84 ; 85 ; PROGRAM START 86 ; 87 ;############################################################################## 88 ;--------------------------------- 89 ; Start chat 90 ;--------------------------------- 91 section _justData 92 _aaa: 93 00000000 202020202020202020- db " Landing Module II:", 0x0d, 0x0a 93 00000009 202020202020202020- 93 00000012 20204C616E64696E67- 93 0000001B 204D6F64756C652049- 93 00000024 493A0D0A 94 00000028 202020202020202020- db " Hello Huston, we have a good landing.", 0x0d, 0x0a 94 00000031 202020202020202020- 94 0000003A 202048656C6C6F2048- 94 00000043 7573746F6E2C207765- 94 0000004C 206861766520612067- 94 00000055 6F6F64206C616E6469- 94 0000005E 6E672E0D0A 95 00000063 0D0A00 db 0x0d, 0x0a, 0x00 96 97 98 ; 99 ; <--- 100 ; 101 section _justCode 102 _entry_point: 103 00000013 BE[0000] mov si, _aaa ; SI -> "Hello Huston...". 104 00000016 E8E7FF call _SHOW_STR ; 105 ; 106 107 section _justData 108 _bbb: 109 00000066 487573746F6E3A0D0A db "Huston:", 0x0d, 0x0a 110 0000006F 476F64204A6F622120- db "God Job! We confirm from here that all systems are ok.", 0x0d, 0x0a 110 00000078 576520636F6E666972- 110 00000081 6D2066726F6D206865- 110 0000008A 726520746861742061- 110 00000093 6C6C2073797374656D- 110 0000009C 7320617265206F6B2E- 110 000000A5 0D0A 111 000000A7 596F752063616E2063- db "You can close the mission. Thank you!", 0x0d, 0x0a, 0x0d, 0x0a, 0x00 111 000000B0 6C6F73652074686520- 111 000000B9 6D697373696F6E2E20- 111 000000C2 5468616E6B20796F75- 111 000000CB 210D0A0D0A00 112 113 section _justCode 114 00000019 BE[6600] mov si, _bbb ; SI -> "God Job!...". 115 0000001C E8E1FF call _SHOW_STR ; 116 ; 117 118 section _justData 119 _ccc: 120 000000D1 202020202020202020- db " Landing Module II:", 0x0d, 0x0a 120 000000DA 202020202020202020- 120 000000E3 20204C616E64696E67- 120 000000EC 204D6F64756C652049- 120 000000F5 493A0D0A 121 000000F9 202020202020202020- db " OK Huston, we shut down the systems", 0x0d, 0x0a 121 00000102 202020202020202020- 121 0000010B 20204F4B2048757374- 121 00000114 6F6E2C207765207368- 121 0000011D 757420646F776E2074- 121 00000126 68652073797374656D- 121 0000012F 730D0A 122 00000132 202020202020202020- db " and close the mission.", 0x0d, 0x0a, 0x00 122 0000013B 202020202020202020- 122 00000144 2020616E6420636C6F- 122 0000014D 736520746865206D69- 122 00000156 7373696F6E2E0D0A00 123 124 section _justCode 125 0000001F BE[D100] mov si, _ccc ; SI -> "OK Huston...". 126 00000022 E8DBFF call _SHOW_STR ; 127 ; 128 ; 129 ;-------------------------------------------------------------------------- 130 ; wait for key press and terminate 131 ;-------------------------------------------------------------------------- 132 00000025 31C0 xor ax, ax ; int 16/ah = 00 : keyboard get keystroke 133 00000027 CD16 int 0x16 ; returns: ah = BIOS scan code 134 ; al = ASCII character 135 ; 136 00000029 EA0000FFFF jmp 0xffff:0000 ; Total system reset since INT 19H hangs 137 ; on HP Elitebook 138 139 140 141 142 143 144 145 146

You can see the program "Learn NASM - 04" (packed inside the SOFTWARE.BIG file) running in the next picture (Fig. C).

Fig. C - "Learn NASM - 04" running in real-mode
Fig. C - "Learn NASM - 04" running in real-mode


  1. SOFTWARE.BIG is the 16-bit binary image file that, once on the root of TEST partition, is loaded in RAM and executed by my bootloader SHUTTLE2. You can read all the story about my bootloader SHUTTLE2 in the chapter VI. [click back]
  2. WARNING!!! If you use the option -f obj instead of -f bin, the meaning of the directive SECTION changes a little bit and the name of the section is also a label so that call _red:_SHOW_STR or jmp _yellow:_nowYellow becomes a legal syntax. [click back]

<PREV.  -  ALL  -  NEXT>

Comments