├── .gitignore ├── README.md ├── LICENSE ├── HelloWorld.asm ├── HelloWorld_procedures.asm ├── efi.inc ├── Notepad.asm ├── ModePagingTest.asm └── Time.asm /.gitignore: -------------------------------------------------------------------------------- 1 | *.efi 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UEFI-32bit-asm-examples 2 | 3 | How to compile: 4 | 5 | fasm BOOTIA32.asm 6 | 7 | How to run: 8 | Rename result file to BOOTIA32.EFI and place it in the following location: 9 | /EFI/boot/BOOTIA32.EFI 10 | 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Szymon Kłos 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /HelloWorld.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; HelloWorld.asm 3 | ; 2015 Szymon Kłos 4 | ; 5 | 6 | format pe dll efi 7 | entry main 8 | 9 | section '.text' code executable readable 10 | 11 | include 'efi.inc' 12 | 13 | main: 14 | push ebp 15 | mov ebp, esp 16 | 17 | ; get args ( ImageHandle and SystemTable pointer ) 18 | 19 | mov ecx, [ebp+8] 20 | mov [ImageHandle], ecx 21 | mov edx, [ebp+12] 22 | mov [SystemTable], edx 23 | 24 | ; checking the signature 25 | 26 | mov eax, EFI_SYSTEM_TABLE.Hdr 27 | add edx, eax 28 | 29 | mov eax, EFI_TABLE_HEADER.Signature 30 | add edx, eax 31 | mov ecx, [edx] 32 | 33 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE 34 | cmp eax, ecx 35 | jne error 36 | 37 | mov ecx, [edx + 4] 38 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE2 39 | cmp eax, ecx 40 | jne error 41 | 42 | clear: 43 | mov eax, EFI_SYSTEM_TABLE.ConOut 44 | mov ecx, [SystemTable] 45 | add ecx, eax 46 | mov ecx, [ecx] 47 | 48 | mov edx, ecx 49 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen 50 | add edx, eax 51 | 52 | push ecx ; [arg] SystemTable.ConOut 53 | 54 | mov edx, [edx] 55 | call edx 56 | add esp, 4 57 | 58 | print_text: 59 | mov eax, EFI_SYSTEM_TABLE.ConOut 60 | mov ecx, [SystemTable] 61 | add ecx, eax 62 | mov ecx, [ecx] 63 | 64 | mov edx, ecx 65 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString 66 | add edx, eax 67 | 68 | lea eax, [text] 69 | push eax ; [arg] text 70 | push ecx ; [arg] SystemTable.ConOut 71 | 72 | mov edx, [edx] 73 | call edx 74 | add esp, 8 75 | 76 | inf_loop: 77 | nop 78 | jmp inf_loop ; infinite loop 79 | 80 | success: 81 | mov eax, EFI_SUCCESS 82 | 83 | pop ebp 84 | retn 85 | 86 | error: 87 | mov eax, 1 88 | pop ebp 89 | retn 90 | 91 | section '.data' data readable writeable 92 | 93 | ImageHandle dd ? 94 | SystemTable dd ? 95 | 96 | text du 'Hello World',13,10,0 97 | 98 | section '.reloc' fixups data discardable 99 | -------------------------------------------------------------------------------- /HelloWorld_procedures.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; HelloWorld_procedures.asm 3 | ; 2015 Szymon Kłos 4 | ; 5 | 6 | format pe dll efi 7 | entry main 8 | 9 | section '.text' code executable readable 10 | 11 | include 'efi.inc' 12 | 13 | ; print args: pointer to string 14 | 15 | print: 16 | mov eax, EFI_SYSTEM_TABLE.ConOut 17 | mov ecx, [SystemTable] 18 | add ecx, eax 19 | mov ecx, [ecx] 20 | 21 | mov edx, ecx 22 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString 23 | add edx, eax 24 | 25 | mov eax, [esp+4] ; [arg] text - currently on stack 26 | push eax 27 | push ecx ; [arg] SystemTable.ConOut 28 | 29 | mov edx, [edx] 30 | call edx 31 | add esp, 8 32 | 33 | ret 34 | 35 | ; clear args: no args 36 | 37 | clear: 38 | mov eax, EFI_SYSTEM_TABLE.ConOut 39 | mov ecx, [SystemTable] 40 | add ecx, eax 41 | mov ecx, [ecx] 42 | 43 | mov edx, ecx 44 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen 45 | add edx, eax 46 | 47 | push ecx ; [arg] SystemTable.ConOut 48 | 49 | mov edx, [edx] 50 | call edx 51 | add esp, 4 52 | 53 | ret 54 | 55 | main: 56 | push ebp 57 | mov ebp, esp 58 | 59 | ; get args ( ImageHandle and SystemTable pointer ) 60 | 61 | mov ecx, [ebp+8] 62 | mov [ImageHandle], ecx 63 | mov edx, [ebp+12] 64 | mov [SystemTable], edx 65 | 66 | ; checking the signature 67 | 68 | mov eax, EFI_SYSTEM_TABLE.Hdr 69 | add edx, eax 70 | 71 | mov eax, EFI_TABLE_HEADER.Signature 72 | add edx, eax 73 | mov ecx, [edx] 74 | 75 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE 76 | cmp eax, ecx 77 | jne error 78 | 79 | mov ecx, [edx + 4] 80 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE2 81 | cmp eax, ecx 82 | jne error 83 | 84 | ; signature OK 85 | 86 | call clear 87 | 88 | lea eax, [text] 89 | push eax ; [arg] text 90 | call print 91 | add esp, 4 92 | 93 | lea eax, [text2] 94 | push eax ; [arg] text 95 | call print 96 | add esp, 4 97 | 98 | inf_loop: 99 | nop 100 | jmp inf_loop ; infinite loop 101 | 102 | success: 103 | mov eax, EFI_SUCCESS 104 | 105 | pop ebp 106 | retn 107 | 108 | error: 109 | mov eax, 1 110 | pop ebp 111 | retn 112 | 113 | section '.data' data readable writeable 114 | 115 | ImageHandle dd ? 116 | SystemTable dd ? 117 | 118 | text du 'Hello World',13,10,0 119 | 120 | section '.reloc' fixups data discardable 121 | -------------------------------------------------------------------------------- /efi.inc: -------------------------------------------------------------------------------- 1 | ; 2 | ; EFI.inc 3 | ; Based on: http://wiki.osdev.org/Uefi.inc 4 | ; 2015 Szymon Kłos 5 | ; 6 | 7 | struc int8 { 8 | . db ? 9 | } 10 | 11 | struc int16 { 12 | align 2 13 | . dw ? 14 | } 15 | 16 | struc int32 { 17 | align 4 18 | . dd ? 19 | } 20 | 21 | struc int64 { 22 | align 8 23 | . dq ? 24 | } 25 | 26 | struc intn { 27 | align 4 28 | . dd ? 29 | } 30 | 31 | struc dptr { 32 | align 4 33 | . dd ? 34 | } 35 | 36 | ; symbols 37 | 38 | EFI_SUCCESS equ 0 39 | 40 | EFI_SYSTEM_TABLE_SIGNATURE equ 20494249h 41 | EFI_SYSTEM_TABLE_SIGNATURE2 equ 54535953h 42 | EFI_RUNTIME_SERVICES_SIGNATURE equ 544e5552h 43 | EFI_RUNTIME_SERVICES_SIGNATURE2 equ 56524553h 44 | 45 | ; helper macro for definition of relative structure member offsets 46 | 47 | macro struct name 48 | { 49 | virtual at 0 50 | name name 51 | end virtual 52 | } 53 | 54 | ; structures 55 | 56 | struc EFI_TABLE_HEADER { 57 | .Signature int64 58 | .Revision int32 59 | .HeaderSize int32 60 | .CRC32 int32 61 | .Reserved int32 62 | } 63 | struct EFI_TABLE_HEADER 64 | 65 | struc EFI_SYSTEM_TABLE { 66 | .Hdr EFI_TABLE_HEADER 67 | .FirmwareVendor dptr 68 | .FirmwareRevision int32 69 | .ConsoleInHandle dptr 70 | .ConIn dptr 71 | .ConsoleOutHandle dptr 72 | .ConOut dptr 73 | .StandardErrorHandle dptr 74 | .StdErr dptr 75 | .RuntimeServices dptr 76 | .BootServices dptr 77 | .NumberOfTableEntries intn 78 | .ConfigurationTable dptr 79 | } 80 | struct EFI_SYSTEM_TABLE 81 | 82 | struc SIMPLE_TEXT_OUTPUT_INTERFACE { 83 | .Reset dptr 84 | .OutputString dptr 85 | .TestString dptr 86 | .QueryMode dptr 87 | .SetMode dptr 88 | .SetAttribute dptr 89 | .ClearScreen dptr 90 | .SetCursorPosition dptr 91 | .EnableCursor dptr 92 | .Mode dptr 93 | } 94 | struct SIMPLE_TEXT_OUTPUT_INTERFACE 95 | 96 | struc EFI_SIMPLE_TEXT_INPUT_PROTOCOL { 97 | .Reset dptr 98 | .ReadKeyStroke dptr 99 | .WaitForKey dptr 100 | } 101 | struct EFI_SIMPLE_TEXT_INPUT_PROTOCOL 102 | 103 | struc EFI_INPUT_KEY { 104 | .ScanCode int16 105 | .UnicodeChar int16 106 | } 107 | struct EFI_INPUT_KEY 108 | 109 | struc EFI_RUNTIME_SERVICES { 110 | .Hdr EFI_TABLE_HEADER 111 | .GetTime dptr 112 | .SetTime dptr 113 | .GetWakeUpTime dptr 114 | .SetWakeUpTime dptr 115 | .SetVirtualAddressMap dptr 116 | .ConvertPointer dptr 117 | .GetVariable dptr 118 | .GetNextVariableName dptr 119 | .SetVariable dptr 120 | .GetNextHighMonotonicCount dptr 121 | .ResetSystem dptr 122 | } 123 | struct EFI_RUNTIME_SERVICES 124 | 125 | struc EFI_TIME { 126 | .Year int16 127 | .Month int8 128 | .Day int8 129 | .Hour int8 130 | .Minute int8 131 | .Second int8 132 | .Pad1 int8 133 | .Nanosecond int32 134 | .TimeZone int16 135 | .Daylight int8 136 | .Pad2 int8 137 | .sizeof rb 1 138 | } 139 | struct EFI_TIME 140 | 141 | -------------------------------------------------------------------------------- /Notepad.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; Notepad.asm 3 | ; 2015 Szymon Kłos 4 | ; 5 | 6 | format pe dll efi 7 | entry main 8 | 9 | section '.text' code executable readable 10 | 11 | include 'efi.inc' 12 | 13 | ; print args: STRING 14 | 15 | print: 16 | mov eax, EFI_SYSTEM_TABLE.ConOut 17 | mov ecx, [SystemTable] 18 | add ecx, eax 19 | mov ecx, [ecx] 20 | 21 | mov edx, ecx 22 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString 23 | add edx, eax 24 | 25 | mov eax, [esp+4] ; [arg] text - currently on stack 26 | push eax 27 | push ecx ; [arg] SystemTable.ConOut 28 | 29 | mov edx, [edx] 30 | call edx 31 | add esp, 8 32 | 33 | ret 34 | 35 | ; clear args: no args 36 | 37 | clear: 38 | mov eax, EFI_SYSTEM_TABLE.ConOut 39 | mov ecx, [SystemTable] 40 | add ecx, eax 41 | mov ecx, [ecx] 42 | 43 | mov edx, ecx 44 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen 45 | add edx, eax 46 | 47 | push ecx ; [arg] SystemTable.ConOut 48 | 49 | mov edx, [edx] 50 | call edx 51 | add esp, 4 52 | 53 | ret 54 | 55 | ; read_key args: no args 56 | ; returns: CHAR16 57 | 58 | read_key: 59 | mov eax, EFI_SYSTEM_TABLE.ConIn 60 | mov ecx, [SystemTable] 61 | add ecx, eax 62 | mov ecx, [ecx] 63 | 64 | mov edx, ecx 65 | mov eax, EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke 66 | add edx, eax 67 | 68 | lea eax, [input_key] 69 | push eax ; [arg] Key 70 | push ecx ; [arg] SystemTable.ConIn 71 | 72 | 73 | mov edx, [edx] 74 | call edx 75 | add esp, 8 76 | 77 | mov eax, EFI_INPUT_KEY.UnicodeChar 78 | lea edx, [input_key] 79 | add edx, eax 80 | 81 | mov eax, 0 82 | mov ax, [edx] 83 | ret 84 | 85 | main: 86 | push ebp 87 | mov ebp, esp 88 | 89 | ; get args ( ImageHandle and SystemTable pointer ) 90 | 91 | mov ecx, [ebp+8] 92 | mov [ImageHandle], ecx 93 | mov edx, [ebp+12] 94 | mov [SystemTable], edx 95 | 96 | ; checking the signature 97 | 98 | mov eax, EFI_SYSTEM_TABLE.Hdr 99 | add edx, eax 100 | 101 | mov eax, EFI_TABLE_HEADER.Signature 102 | add edx, eax 103 | mov ecx, [edx] 104 | 105 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE 106 | cmp eax, ecx 107 | jne error 108 | 109 | mov ecx, [edx + 4] 110 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE2 111 | cmp eax, ecx 112 | jne error 113 | 114 | ; signature OK 115 | 116 | call clear 117 | 118 | lea eax, [text] 119 | push eax ; [arg] text 120 | call print 121 | add esp, 4 122 | 123 | inf_loop: 124 | 125 | ; read input 126 | 127 | call read_key 128 | 129 | ; move returned char to the buffer 130 | 131 | lea edx, [buffer] 132 | mov [edx], ax 133 | 134 | ; print returned char 135 | 136 | push edx 137 | call print 138 | add esp, 4 139 | 140 | jmp inf_loop ; infinite loop 141 | 142 | success: 143 | mov eax, EFI_SUCCESS 144 | 145 | pop ebp 146 | retn 147 | 148 | error: 149 | mov eax, 1 150 | pop ebp 151 | retn 152 | 153 | section '.data' data readable writeable 154 | 155 | ImageHandle dd ? 156 | SystemTable dd ? 157 | 158 | text du 'Notepad',13,10,0 159 | input_key EFI_INPUT_KEY 160 | du 0 161 | buffer du 0 162 | 163 | section '.reloc' fixups data discardable 164 | -------------------------------------------------------------------------------- /ModePagingTest.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; ModePagingTest.asm 3 | ; 2015 Szymon Kłos 4 | ; 5 | 6 | format pe dll efi 7 | entry main 8 | 9 | section '.text' code executable readable 10 | 11 | include 'efi.inc' 12 | 13 | ; print args: STRING 14 | 15 | print: 16 | mov eax, EFI_SYSTEM_TABLE.ConOut 17 | mov ecx, [SystemTable] 18 | add ecx, eax 19 | mov ecx, [ecx] 20 | 21 | mov edx, ecx 22 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString 23 | add edx, eax 24 | 25 | mov eax, [esp+4] ; [arg] text - currently on stack 26 | push eax 27 | push ecx ; [arg] SystemTable.ConOut 28 | 29 | mov edx, [edx] 30 | call edx 31 | add esp, 8 32 | 33 | ret 34 | 35 | ; new_line args: no args 36 | 37 | new_line: 38 | lea eax, [text_new_line] 39 | push eax ; [arg] text 40 | call print 41 | add esp, 4 42 | ret 43 | 44 | ; int_to_string args: INT32 45 | ; returns: STRING in buffer_to_string 46 | 47 | int_to_string: 48 | mov eax, [esp+4] 49 | push ebx 50 | push esi 51 | 52 | mov ebp, 10 53 | xor edx, edx 54 | mov ecx, 0 55 | mov esi, 0 56 | lea ebx, [buffer_to_string] 57 | 58 | loop_its: 59 | div ebp 60 | add dl, 48 61 | push edx 62 | xor edx, edx 63 | inc esi 64 | cmp eax, 0 65 | jnz loop_its 66 | 67 | loop_its_2: 68 | pop edx 69 | mov [ebx+ecx], dl 70 | add ecx, 2 71 | xor edx, edx 72 | dec esi 73 | cmp esi, 0 74 | jnz loop_its_2 75 | 76 | mov dl, 0 77 | mov [ebx+ecx], dl 78 | 79 | pop esi 80 | pop ebx 81 | ret 82 | 83 | ; clear args: no args 84 | 85 | clear: 86 | mov eax, EFI_SYSTEM_TABLE.ConOut 87 | mov ecx, [SystemTable] 88 | add ecx, eax 89 | mov ecx, [ecx] 90 | 91 | mov edx, ecx 92 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen 93 | add edx, eax 94 | 95 | push ecx ; [arg] SystemTable.ConOut 96 | 97 | mov edx, [edx] 98 | call edx 99 | add esp, 4 100 | 101 | ret 102 | 103 | main: 104 | push ebp 105 | mov ebp, esp 106 | 107 | ; get args ( ImageHandle and SystemTable pointer ) 108 | 109 | mov ecx, [ebp+8] 110 | mov [ImageHandle], ecx 111 | mov edx, [ebp+12] 112 | mov [SystemTable], edx 113 | 114 | ; checking the signature 115 | 116 | mov eax, EFI_SYSTEM_TABLE.Hdr 117 | add edx, eax 118 | 119 | mov eax, EFI_TABLE_HEADER.Signature 120 | add edx, eax 121 | mov ecx, [edx] 122 | 123 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE 124 | cmp eax, ecx 125 | jne error 126 | 127 | mov ecx, [edx + 4] 128 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE2 129 | cmp eax, ecx 130 | jne error 131 | 132 | ; signature OK 133 | ; checking EFI_RUNTOME_SERVICES signature 134 | 135 | mov eax, EFI_SYSTEM_TABLE.RuntimeServices 136 | mov edx, [SystemTable] 137 | add edx, eax 138 | mov edx, [edx] 139 | 140 | mov eax, EFI_RUNTIME_SERVICES.Hdr 141 | add edx, eax 142 | 143 | mov eax, EFI_TABLE_HEADER.Signature 144 | add edx, eax 145 | mov ecx, [edx] 146 | 147 | mov eax, EFI_RUNTIME_SERVICES_SIGNATURE 148 | cmp eax, ecx 149 | jne error 150 | 151 | mov ecx, [edx + 4] 152 | mov eax, EFI_RUNTIME_SERVICES_SIGNATURE2 153 | cmp eax, ecx 154 | jne error 155 | 156 | ; signature OK 157 | 158 | call clear 159 | 160 | ; print CR3 label 161 | 162 | lea eax, [text_CR3] 163 | push eax 164 | call print 165 | add esp, 4 166 | 167 | ; print CR3 Register value 168 | 169 | mov eax, cr3 170 | 171 | push eax 172 | call int_to_string 173 | add esp, 4 174 | 175 | lea eax, [buffer_to_string] 176 | push eax 177 | call print 178 | add esp, 4 179 | 180 | call new_line 181 | 182 | ; print CR0 label 183 | 184 | lea eax, [text_CR0] 185 | push eax 186 | call print 187 | add esp, 4 188 | 189 | ; print CR0 Register value 190 | 191 | mov eax, cr0 192 | 193 | push eax 194 | call int_to_string 195 | add esp, 4 196 | 197 | lea eax, [buffer_to_string] 198 | push eax 199 | call print 200 | add esp, 4 201 | 202 | call new_line 203 | 204 | ; check mode 205 | 206 | mov eax, cr0 207 | bt eax, 0 208 | 209 | jc protected_mode 210 | 211 | ; real_mode 212 | 213 | lea eax, [text_RM] 214 | push eax 215 | call print 216 | add esp, 4 217 | 218 | call new_line 219 | 220 | inf_loop: 221 | nop 222 | jmp inf_loop ; infinite loop 223 | 224 | success: 225 | mov eax, EFI_SUCCESS 226 | 227 | pop ebp 228 | retn 229 | 230 | protected_mode: 231 | lea eax, [text_PM] 232 | push eax 233 | call print 234 | add esp, 4 235 | 236 | call new_line 237 | 238 | mov eax, cr0 239 | bt eax, 31 240 | 241 | jc paging_on 242 | 243 | lea eax, [text_no_paging] 244 | jmp print_paging 245 | 246 | paging_on: 247 | lea eax, [text_paging] 248 | 249 | print_paging: 250 | push eax 251 | call print 252 | add esp, 4 253 | 254 | call new_line 255 | 256 | jmp inf_loop 257 | 258 | error: 259 | mov eax, 1 260 | pop ebp 261 | retn 262 | 263 | section '.data' data readable writeable 264 | 265 | ImageHandle dd ? 266 | SystemTable dd ? 267 | 268 | text_CR3 du 'CR3: ',0 269 | text_CR0 du 'CR0: ',0 270 | text_PM du 'Protected Mode',0 271 | text_RM du 'Real Mode',0 272 | text_paging du 'Paging Enabled',0 273 | text_no_paging du 'Paging Disabled',0 274 | text_new_line du 13,10,0 275 | 276 | buffer du 0 277 | buffer_to_string du 0,0,0,0,0,0,0,0,0,0,0,0,0 278 | 279 | section '.reloc' fixups data discardable 280 | -------------------------------------------------------------------------------- /Time.asm: -------------------------------------------------------------------------------- 1 | ; 2 | ; BOOTIA32.asm 3 | ; 2015 Szymon Kłos 4 | ; 5 | 6 | format pe dll efi 7 | entry main 8 | 9 | section '.text' code executable readable 10 | 11 | include 'efi.inc' 12 | 13 | ; print args: STRING 14 | 15 | print: 16 | mov eax, EFI_SYSTEM_TABLE.ConOut 17 | mov ecx, [SystemTable] 18 | add ecx, eax 19 | mov ecx, [ecx] 20 | 21 | mov edx, ecx 22 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString 23 | add edx, eax 24 | 25 | mov eax, [esp+4] ; [arg] text - currently on stack 26 | push eax 27 | push ecx ; [arg] SystemTable.ConOut 28 | 29 | mov edx, [edx] 30 | call edx 31 | add esp, 8 32 | 33 | ret 34 | 35 | ; new_line args: no args 36 | 37 | new_line: 38 | lea eax, [text_new_line] 39 | push eax ; [arg] text 40 | call print 41 | add esp, 4 42 | ret 43 | 44 | ; int_to_string args: INT32 45 | ; returns: STRING in buffer_to_string 46 | 47 | int_to_string: 48 | mov eax, [esp+4] 49 | push ebx 50 | push esi 51 | 52 | mov ebp, 10 53 | xor edx, edx 54 | mov ecx, 0 55 | mov esi, 0 56 | lea ebx, [buffer_to_string] 57 | 58 | loop_its: 59 | div ebp 60 | add dl, 48 61 | push edx 62 | xor edx, edx 63 | inc esi 64 | cmp eax, 0 65 | jnz loop_its 66 | 67 | loop_its_2: 68 | pop edx 69 | mov [ebx+ecx], dl 70 | add ecx, 2 71 | xor edx, edx 72 | dec esi 73 | cmp esi, 0 74 | jnz loop_its_2 75 | 76 | mov dl, 0 77 | mov [ebx+ecx], dl 78 | 79 | pop esi 80 | pop ebx 81 | ret 82 | 83 | ; clear args: no args 84 | 85 | clear: 86 | mov eax, EFI_SYSTEM_TABLE.ConOut 87 | mov ecx, [SystemTable] 88 | add ecx, eax 89 | mov ecx, [ecx] 90 | 91 | mov edx, ecx 92 | mov eax, SIMPLE_TEXT_OUTPUT_INTERFACE.ClearScreen 93 | add edx, eax 94 | 95 | push ecx ; [arg] SystemTable.ConOut 96 | 97 | mov edx, [edx] 98 | call edx 99 | add esp, 4 100 | 101 | ret 102 | 103 | main: 104 | push ebp 105 | mov ebp, esp 106 | 107 | ; get args ( ImageHandle and SystemTable pointer ) 108 | 109 | mov ecx, [ebp+8] 110 | mov [ImageHandle], ecx 111 | mov edx, [ebp+12] 112 | mov [SystemTable], edx 113 | 114 | ; checking the signature 115 | 116 | mov eax, EFI_SYSTEM_TABLE.Hdr 117 | add edx, eax 118 | 119 | mov eax, EFI_TABLE_HEADER.Signature 120 | add edx, eax 121 | mov ecx, [edx] 122 | 123 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE 124 | cmp eax, ecx 125 | jne error 126 | 127 | mov ecx, [edx + 4] 128 | mov eax, EFI_SYSTEM_TABLE_SIGNATURE2 129 | cmp eax, ecx 130 | jne error 131 | 132 | ; signature OK 133 | ; checking EFI_RUNTOME_SERVICES signature 134 | 135 | mov eax, EFI_SYSTEM_TABLE.RuntimeServices 136 | mov edx, [SystemTable] 137 | add edx, eax 138 | mov edx, [edx] 139 | 140 | mov eax, EFI_RUNTIME_SERVICES.Hdr 141 | add edx, eax 142 | 143 | mov eax, EFI_TABLE_HEADER.Signature 144 | add edx, eax 145 | mov ecx, [edx] 146 | 147 | mov eax, EFI_RUNTIME_SERVICES_SIGNATURE 148 | cmp eax, ecx 149 | jne error 150 | 151 | mov ecx, [edx + 4] 152 | mov eax, EFI_RUNTIME_SERVICES_SIGNATURE2 153 | cmp eax, ecx 154 | jne error 155 | 156 | ; signature OK 157 | 158 | inf_loop: 159 | 160 | call clear 161 | 162 | ; get time 163 | 164 | mov eax, EFI_SYSTEM_TABLE.RuntimeServices 165 | mov edx, [SystemTable] 166 | add edx, eax 167 | mov edx, [edx] 168 | 169 | mov eax, EFI_RUNTIME_SERVICES.GetTime 170 | add edx, eax 171 | mov edx, [edx] 172 | 173 | mov eax, 0 174 | push eax 175 | lea eax, [time] 176 | push eax 177 | 178 | call edx 179 | 180 | add esp, 8 181 | 182 | ; print time label 183 | 184 | lea eax, [text_time] 185 | push eax 186 | call print 187 | add esp, 4 188 | 189 | ; print hours 190 | 191 | lea ecx, [time] 192 | mov edx, EFI_TIME.Hour 193 | add ecx, edx 194 | mov eax, 0 195 | mov al, [ecx] 196 | 197 | push eax 198 | call int_to_string 199 | add esp, 4 200 | 201 | lea eax, [buffer_to_string] 202 | push eax 203 | call print 204 | add esp, 4 205 | 206 | ; print separator 207 | 208 | lea eax, [buffer] 209 | mov dl, ':' 210 | mov [eax], dl 211 | mov dl, 0 212 | mov [eax+2], dl 213 | push eax 214 | call print 215 | add esp, 4 216 | 217 | ; print minutes 218 | 219 | lea ecx, [time] 220 | mov edx, EFI_TIME.Minute 221 | add ecx, edx 222 | mov eax, 0 223 | mov al, [ecx] 224 | 225 | push eax 226 | call int_to_string 227 | add esp, 4 228 | 229 | lea eax, [buffer_to_string] 230 | push eax 231 | call print 232 | add esp, 4 233 | 234 | ; print separator 235 | 236 | lea eax, [buffer] 237 | mov dl, ':' 238 | mov [eax], dl 239 | mov dl, 0 240 | mov [eax+2], dl 241 | push eax 242 | call print 243 | add esp, 4 244 | 245 | ; print seconds 246 | 247 | lea ecx, [time] 248 | mov edx, EFI_TIME.Second 249 | add ecx, edx 250 | mov eax, 0 251 | mov al, [ecx] 252 | 253 | push eax 254 | call int_to_string 255 | add esp, 4 256 | 257 | lea eax, [buffer_to_string] 258 | push eax 259 | call print 260 | add esp, 4 261 | 262 | call new_line 263 | 264 | jmp inf_loop ; infinite loop 265 | 266 | success: 267 | mov eax, EFI_SUCCESS 268 | 269 | pop ebp 270 | retn 271 | 272 | error: 273 | mov eax, 1 274 | pop ebp 275 | retn 276 | 277 | section '.data' data readable writeable 278 | 279 | ImageHandle dd ? 280 | SystemTable dd ? 281 | 282 | text_time du 'Time: ',0 283 | text_new_line du 13,10,0 284 | 285 | time EFI_TIME 286 | buffer du 0 287 | buffer_to_string du 0,0,0,0,0,0,0,0,0,0,0,0,0 288 | 289 | section '.reloc' fixups data discardable 290 | --------------------------------------------------------------------------------