Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Using NASM / Re: NASM tutorial for Windows (7+), console and windows
« Last post by nasmer on September 19, 2021, 08:55:33 PM »
Thanks alot for your effort from me too.
12
Using NASM / Re: Debugging Multiple Files
« Last post by Frank Kotler on September 19, 2021, 04:54:06 AM »
I am not much good at gdb.
Adding "-F dwarf" to Nasm's command line might help.
Starting with a single byte instruction - "nop" will do - may help.
Do not give ld "-s".
Good luck!

Best,
Frank


13
Using NASM / Debugging Multiple Files
« Last post by HackerWithoutACause on September 19, 2021, 04:16:49 AM »
For the sake of project organization I split my project into multiple files using
Code: [Select]
%include "alloc.s", but now I have the problem that I can not view the lines of assembly with GDB I am using the command
Code: [Select]
nasm -f elf64 -o main.o main.s -g && ld main.o -o main && gdb main to compile the assembly. How can I get NASM and GDB to properly display the lines of assembly that it is running?

I am using NASM version 2.15.05 and GDB version 10.2.
14
Using NASM / Re: Compiling EFI file from ASM code
« Last post by Frank Kotler on September 06, 2021, 03:00:37 PM »
Thank you !

Best,
Frank

15
Using NASM / Re: Compiling EFI file from ASM code
« Last post by JD9999 on September 06, 2021, 07:57:39 AM »
I've done it (with much learning from other implementations)!

Have a look at my example code here (https://forum.nasm.us/index.php?topic=2786.0) if you're interested.

Thanks,
Jamie
16
Example Code / UEFI implementation in NASM
« Last post by JD9999 on September 06, 2021, 07:56:32 AM »
Hi everyone!

With much help from previous implementations of a nasm uefi interface:
- BrianOtto's implementation: https://github.com/BrianOtto/nasm-uefi
- Charles AP's implementation: https://github.com/charlesap/nasm-uefi

I have written a basic UEFI application!
This looks much more like the second implementation than the first, because I wanted to build it as a single EFI file without a linker.

What does it do?
It displays the words "Wait a second..."
Then it waits a second
Then it displays the words "Hi JD9999!"

How do I run this code?
To compile this code, run the command:
Code: [Select]
nasm -f bin loader.asm -o BOOTX64.efi(change loader.asm to whatever you name the file)

This produces an EFI file, which you need to copy to a USB in the directory
Code: [Select]
F:\EFI\BOOT\BOOTX64.efi(change F: to the drive letter as necessary)

Then just boot off the USB device (or whatever type of device it is)

Where's the code?
Here it is:
Code: [Select]
BITS 64
org 0x00100000 ;Space for a small stack?

;**************
;*** HEADER ***
;**************

section .header
DOS_HEADER:
   dw 0x5a4d ;DOS Magic number
   times 29 dw 0 ;Zeroes
   dd 0x00000080 ;Address of PE header

DOS_STUB:
   ; I don't know how to write this as text, so you get zeroes
   times 32 dw 0

PE_HEADER:
   dd 0x00004550 ;PE Magic number
   dw 0x8664 ;Building for x86 architecture
   dw 2 ;Two sections (.text, .data)
   dd 0x5ed4b58 ;number of seconds between 00:00:00 1st January 1970 and 00:00:00 1st July 2021
   dd 0x0 ;No symbol table
   dd 0x0 ;No symbols in the non-existent symbol table!
   dw oSize ;The size of the entire optional header. See the OPTIONAL_HEADER_END label for the calculation.
   dw 0x1002 ;Is a valid image file, is a system file. No other fancy characteristics.

oSize equ OPTIONAL_HEADER_END - OPTIONAL_HEADER_STANDARD_FIELDS

OPTIONAL_HEADER_STANDARD_FIELDS: ;Not actually optional
   dw 0x020b ;PE32+ Executable. I want my 64-bit registers!
   dw 0x0 ;What linker?
   dd 1024 ;The size of the code segment
   dd 1024 ;The size of the data segment
   dd 0x0 ;No .bss section. All variables to be initialised.
   dd 1024 ;The program's entry point
   dd 1024 ;The program's first instruction. Same as the start of the code execution. Duh.

OPTIONAL_HEADER_WINDOWS_FIELDS: ;This is required for UEFI applications too. Trust me, plenty of debugging went into that discovery.
   dq 0x00100000 ;The entry point of the image
   dd 0x1024 ;The section alignment
   dd 0x1024 ;The file alignment
   dw 0x0 ;No operating system requirements
   dw 0x0 ;Stil no operating system requirements
   dw 0x0 ;Major image version number
   dw 0x1 ;Minor image version number
   dw 0x0 ;Major subsystem version. Doesn't matter, as long as it supports UEFI.
   dw 0x0 ;Minor subsystem version. Doesn't matter, as long as it supports UEFI.
   dd 0x0 ;A dedicated zero
   dd 3072 ;Image size
   dd 1024 ;Header size
   dd 0x0 ;Checksum //TODO ADD LATER
   dw 0x000A ;UEFI Subsystem number.
   dw 0x0 ;Not a DLL, so this can be zero

   ;Using PE32+ file type, so the following are dqs, not dds
   dq 0x8000 ;Amount of stack space to reserve
   dq 0x8000 ;Amount of stack space to commit immediately
   dq 0x8000 ;Amount of local heap space to reserve
   dq 0x0 ;Amount of local heap space to commit immediately. Hopefully not needed.
   dd 0x0 ;Another four bytes dedicated to being zeroes
   dd 0x0 ;Number of data dictionary entries

;OPTIONAL_HEADER_DATA_DIRECTORIES: ;We don't have any special sections, so we don't need this header!

OPTIONAL_HEADER_END: ;This label is required for calculating value of oSize

SECTION_TABLE: ;as if you don't have enough information already :\
.1: ;text section
   dq `.text` ;The name of the text section
   dd 1024 ;virtual size.
   dd 1024 ;virtual entry point address.
   dd 1024 ;actual size.
   dd 1024 ;actual entry point address.
   dd 0 ;No relocations
   dd 0 ;No line numbers
   dw 0 ;No relocations
   dw 0 ;No line numbers
   dd 0x60000020 ;Contains executable code, can be executed as code, can be read.

.2: ;data section
   dq `.data` ;The name of the data section
   dd 1024 ;virtual size.
   dd 2048 ;virtual entry point address.
   dd 1024 ;actual size.
   dd 2048 ;actual entry point address.
   dd 0 ;No relocations
   dd 0 ;No line numbers
   dw 0 ;No relocations
   dw 0 ;No line numbers
   dd 0xc0000040 ;Contains initialised data, can be read, can be written to.

times 1024 - ($-$$) db 0 ;alignment

;*****************
;*** MAIN CODE ***
;*****************

section .text follows=.header
vars:
   ;Function return codes.
   EFI_SUCCESS equ 0
   
   ;Offsets for loading function addresses
   OFFSET_TABLE_BOOT_SERVICES equ 96
   OFFSET_TABLE_ERROR_CONSOLE equ 80
   OFFSET_TABLE_OUTPUT_CONSOLE equ 64
   OFFSET_TABLE_RUNTIME_SERVICES equ 88
   OFFSET_BOOT_EXIT_PROGRAM equ 216
   OFFSET_BOOT_STALL equ 248
   OFFSET_CONSOLE_OUTPUT_STRING equ 8

   ;Numbers used in the program.
   waitTime equ 1000000 ;One million microseconds, equals one second

start:
   sub rsp, 6*8+8 ; Copied from Charles AP's implementation, fix stack alignment issue (Thanks Charles AP!)

   ;Start moving handoff variables.
   mov [EFI_HANDLE], rcx
   mov [EFI_SYSTEM_TABLE], rdx
   mov [EFI_RETURN], rsp

   ;Set up necessary boot services functions
   add rdx, OFFSET_TABLE_BOOT_SERVICES ;get boot services table
   mov rcx, [rdx]
   mov [BOOT_SERVICES], rcx
   add rcx, OFFSET_BOOT_EXIT_PROGRAM ;get exit function from boot services table
   mov rdx, [rcx]
   mov [BOOT_SERVICES_EXIT], rdx
   mov rcx, [BOOT_SERVICES]
   add rcx, OFFSET_BOOT_STALL ;get stall function from boot services table
   mov rdx, [rcx]
   mov [BOOT_SERVICES_STALL], rdx

   ;Set up necessary console functions
   mov rdx, [EFI_SYSTEM_TABLE]
   add rdx, OFFSET_TABLE_ERROR_CONSOLE ;get error console table
   mov rcx, [rdx]
   mov [CONERR], rcx
   add rcx, OFFSET_CONSOLE_OUTPUT_STRING ;get output string function from console table
   mov rdx, [rcx]
   mov [CONERR_PRINT_STRING], rdx

   mov rdx, [EFI_SYSTEM_TABLE]
   add rdx, OFFSET_TABLE_OUTPUT_CONSOLE ;get output console table
   mov rcx, [rdx]
   mov [CONOUT], rcx
   add rcx, OFFSET_CONSOLE_OUTPUT_STRING ;get output string function from console table
   mov rdx, [rcx]
   mov [CONOUT_PRINT_STRING], rdx

   ;Set up necessary runtime services functions
   mov rdx, [EFI_SYSTEM_TABLE]
   add rdx, OFFSET_TABLE_RUNTIME_SERVICES ;get runtime services table
   mov rcx, [rdx]
   mov [RUNTIME_SERVICES], rcx

   ;Clear some registers for use.
   xor rcx, rcx
   xor rdx, rdx
   xor r8, r8

   ;Print a string
   mov rcx, [CONOUT]
   lea rdx, [waitString]
   call [CONOUT_PRINT_STRING]

   ;Wait a second so that the user can read the string
   mov rcx, waitTime
   call [BOOT_SERVICES_STALL]

   ;Print a string
   mov rcx, [CONOUT]
   lea rdx, [hello]
   call [CONOUT_PRINT_STRING]

   ;Return back to the UEFI with success!
   mov rcx, [EFI_HANDLE]
   mov rdx, EFI_SUCCESS
   mov r8, 1
   call [BOOT_SERVICES_EXIT]

   ret

times 1024 - ($-$$) db 0 ;alignment

;************
;*** DATA ***
;************

section .data follows=.text
dataStart:
   ;Handover variables
   EFI_HANDLE dq 0
   EFI_SYSTEM_TABLE dq 0
   EFI_RETURN dq 0

   ;Accessing functions of EFI system table
   BOOT_SERVICES dq 0
   BOOT_SERVICES_EXIT dq 0 ;This one exits the program, not just stop boot services!
   BOOT_SERVICES_STALL dq 0
   CONERR dq 0
   CONERR_PRINT_STRING dq 0
   CONOUT dq 0
   CONOUT_PRINT_STRING dq 0
   RUNTIME_SERVICES dq 0
   
   ;Strings used in the program.
   waitString db __utf16__ `Wait a second...\r\n\0`
   hello db __utf16__ `Hi JD9999!\r\n\0`

times 1024 - ($-$$) db 0 ;alignment

Things I've learned
I learned lots of things, but here are some things I wanted to share for people who want to do something similar in the future:
  • A relocation section is not required.
  • Section alignments are necessary. Sometimes you have to represent it as a hexadecimal, and something you have to reference it as a decimal. You can see above the difference between 'dd 1024' and 'dd 0x1024' above to know when to use which one.
  • Some optional things are not optional, including the "Windows-Specific Fields". They are required for UEFI (see https://docs.microsoft.com/en-us/windows/win32/debug/pe-format for a full description of the PE header)
  • The offsets from the EFI_SYSTEM_TABLE point to pointers, but are themselves not pointer addresses. This means don't use the [] for offsets. But use it for the combined value of the table and the offset to get the pointer to the function call you need!

Summary
If you have any improvements you would like to suggest, please do! I always like improving things to make them better.

Hope this helps someone!
17
Announcements / NASM on Visual Studio 2019
« Last post by Crysein on September 02, 2021, 01:55:12 PM »
Hello,

If you wish to build NASM on Windows, ive done the portability to VS2019

The NASM version is the 2.15.05

I plan to translate it to C# in the future.
18
Int 0x10 is how to switch video modes in general, including standard VGA mode, etc. For example mode number 0 is a 40 column text mode. So that begs the question, what is the mode number for vesa mode?
I've already gave you the links for VBE3 specification and for a VBE tutorial. Read them.
19
Programming with NASM / Re: How do I switch monitor to 24bit or 32bit color in 16bit ASM?
« Last post by ben321 on September 01, 2021, 11:42:24 PM »
It isn't easy to use WIDESCREEN graphics modes without the help of vendors drivers, but you can use relative high resolution graphics modes using VESA BIOS EXTENSIONS (VBE), through int 0x10, and deal with "banks" of memory to fill the framebuffer, in real mode.

It's easy to switch to those modes (1024 x 768 with 24 bits RGB pixels, for example) and use a 'linear frame buffer' in PROTECTED MODE. In real mode you have to use `int 0x10` to switch portions of the screen and map them in Video Memory. Why is that? Consider that real mode video memory start at physical address 0xA0000 and spans to 0xBFFFF. This gives you 128 KiB of memory available to video. With 1024 x 768, RGB mode you must have a 1024*768*3 bytes frame buffer: almost 2.4 MiB of memory (18 times more memory), sou you must break this in chunks of 64 KiB (1 segment).

Here's the specfication for VBE 3 (the last spec available), and an article from OSDev to help you understand how to use it: VESA Tutorial

Int 0x10 is how to switch video modes in general, including standard VGA mode, etc. For example mode number 0 is a 40 column text mode. So that begs the question, what is the mode number for vesa mode?
20
Programming with NASM / Re: Retrieving element from an array
« Last post by tysonprogrammer on September 01, 2021, 09:58:52 PM »
Thanks guys for your wisdom. I ended up using bx and it worked like a charm. I knew I was close, I probably could of dug through my masm book to find it but thought this was quicker, and it was. Just took me a few days to respond.

thanks,
Tyson
Pages: 1 [2] 3 4 ... 10