From c00c870fc49dff0b55701c10810bf92f99f2fa8e Mon Sep 17 00:00:00 2001 From: Jonas Hvid Date: Sat, 7 Mar 2020 17:33:41 +0100 Subject: [PATCH] Implement a subroutine to print a byte-string of a given length --- uefi/main.asm | 78 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/uefi/main.asm b/uefi/main.asm index aa34ddc..e038659 100644 --- a/uefi/main.asm +++ b/uefi/main.asm @@ -1,6 +1,16 @@ +;; vim: syntax=fasm + format pe64 dll efi entry main +;; [TODO] We need to provide the following: +;; - [X] Print a string of a given length +;; - [ ] Print a single character +;; - [ ] Terminate the program (? - What should this do?) +;; - [ ] Read a single character +;; - This should allow the user to type in a string, and then feed the +;; buffer to us one character at a time. + ;; #region Structs ;; Based on https://wiki.osdev.org/Uefi.inc @@ -46,20 +56,72 @@ main: ; At program startup, RDX contains an EFI_SYSTEM_TABLE*. mov [system_table], rdx - mov rcx, [system_table] ; EFI_SYSTEM_TABLE* rcx - mov rcx, [rcx + EFI_SYSTEM_TABLE.ConOut] ; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* rcx - mov rdx, hello_world_string - ; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* rcx, CHAR16* rdx) - mov rbx, [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString] ; EFI_TEXT_STIRNG rbx + mov rcx, hello_string + mov rdx, hello_string.len + call print_string + + mov rcx, hello_string + mov rdx, hello_string.len + call print_string + + mov rcx, hello_string + mov rdx, hello_string.len + call print_string + + ret + +;; Print a string of the given length. +;; +;; Inputs: +;; - RCX = String buffer +;; - RDX = String length +print_string: + mov r8, rcx + mov r9, rdx + + mov r10, r9 + add r10, r10 + + ; We take an input string of bytes without any terminator. We need to turn + ; this string into a string of words, terminated by a null character. + mov rcx, 0 + mov rsi, 0 +.copy_byte: + cmp rcx, r10 + je .done + + mov al, byte [r8 + rsi] + lea rdx, [.output_buffer + rcx] + mov byte [rdx], al + inc rcx + inc rsi + + lea rdx, [.output_buffer + rcx] + mov byte [rdx], 0 + inc rcx + + jmp .copy_byte +.done: + lea rdx, [.output_buffer + r10] + mov byte [rdx], 0 + + ; At this point we have our null-terminated word-string at .output_buffer. Now + ; we just need to print it. + + mov rcx, [system_table] ; EFI_SYSTEM_TABLE* rcx + mov rcx, [rcx + EFI_SYSTEM_TABLE.ConOut] ; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* rcx + mov rdx, .output_buffer + mov rbx, [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString] ; EFI_TEXT_STRING rbx sub rsp, 32 call rbx add rsp, 32 - - mov rax, 0 ret section '.data' readable writable system_table dq ? ; EFI_SYSTEM_TABLE* -hello_world_string du 'Hello world!', 0xC, 0xA, 0 +hello_string db 'Hello, world!', 0xD, 0xA, 'Here is some more text.', 0xD, 0xA +.len = $ - hello_string + +print_string.output_buffer rq 0x400 -- 2.39.2