Author Topic: How do I write an EFI application in NASM?  (Read 18456 times)

Offline ben321

  • Full Member
  • **
  • Posts: 185
How do I write an EFI application in NASM?
« on: January 15, 2022, 12:55:47 PM »
I'm aware of the fact when I boot a computer to EFI console that that is actually running in 32bit mode like Windows OS, and in fact the type of program I can execute from the console are 32bit PE EXE files (not DOS 16bit MZ EXE files). This means I should be able to write a program in notepad and assemble in NASM and then use a linker to create a PE EXE file, and expect a computer booted in an EFI console to be able to run that EXE.

But I have one question. What functions (even basic text-printing functions) do I have access to? I know it can't be ANY functions that depend on Windows DLLs. They MUST be functions builtin to the EFI boot environment itself. I assume that I would call the functions with INT (interrupt x86 instruction), and I assume they are standardized (much like BIOS interrupts on older PCs). If anybody here knows, please tell me how to call EFI functions.

Offline Franciswalser

  • Jr. Member
  • *
  • Posts: 7
Re: How do I write an EFI application in NASM?
« Reply #1 on: January 23, 2023, 08:18:08 AM »
When a computer is booted to the EFI console, it runs in 32-bit mode and can execute 32-bit PE EXE files. However, the functions that are available to you while running in the EFI console are limited to those that are built into the EFI boot environment itself. These functions are typically provided by the firmware or the EFI bootloader, and are not dependent on Windows DLLs.

You can call EFI functions by using the INT instruction, which is used to invoke an interrupt handler. The EFI firmware provides a set of standard interrupt handlers, known as the EFI Application Programming Interface (API), that can be called to perform various tasks, such as printing text to the screen, reading or writing to the file system, and communicating with other devices.

The EFI firmware provides a set of functions that are defined in the EFI API, you can use these functions by calling them through their memory address.

Some of the functions that are provided by the EFI API include: PartyCityFeedback.com


EFI_BOOT_SERVICES.Print: This function is used to print text to the screen.
EFI_BOOT_SERVICES.ReadKeyStroke: This function is used to read keyboard input.
EFI_BOOT_SERVICES.LocateProtocol: This function is used to locate a protocol, such as the file system protocol.
EFI_BOOT_SERVICES.AllocatePool: This function is used to allocate
« Last Edit: January 24, 2023, 04:11:06 AM by Franciswalser »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 374
  • Country: br
Re: How do I write an EFI application in NASM?
« Reply #2 on: January 23, 2023, 10:39:03 AM »
When a computer is booted to the EFI console, it runs in 32-bit mode...
Yep, but you can run in x86-64 mode as well.

Quote from: Franciswalser
You can call EFI functions by using the INT instruction, ...

That's not how efi interfaces works. At the program entry point two arguments are passed: EFI_HANDLE ImageHandle and EFI_SYSTEM_TABLE *SystemTable. Through SystemTable pointer you get the other interfaces like boot services and runtime services.

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 374
  • Country: br
Re: How do I write an EFI application in NASM?
« Reply #3 on: January 23, 2023, 01:26:58 PM »
A small example for i386 mode, assuming by "application" you mean "bootloader":
Change main to _start if you want to avoid -e option with ld.

PS: EFI_BOOT_SERVICES.Print() and EFI_BOOT_SERVICES.ReadKeyStroke() don't exist. Print() is a wrapper function, defined in a external library, to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString() and ReadKeyStroke() is a function on EFI_SIMPLE_TEXT_INPUT_PROTOCOL. They are available at interfaces pointed by ConIn and ConOut, at EFI_BOOT_SERVICES.

I strongly recommend to read UEFI specification (download, at least, version 2.7 - most BIOSes support this one). There you can find the entire documentation of how EFI works and how to use it in i386, x86-64, ARM, and other platforms.
« Last Edit: January 23, 2023, 01:42:14 PM by fredericopissarra »

Offline ben321

  • Full Member
  • **
  • Posts: 185
Re: How do I write an EFI application in NASM?
« Reply #4 on: August 03, 2024, 08:28:13 PM »
A small example for i386 mode, assuming by "application" you mean "bootloader":
Change main to _start if you want to avoid -e option with ld.

PS: EFI_BOOT_SERVICES.Print() and EFI_BOOT_SERVICES.ReadKeyStroke() don't exist. Print() is a wrapper function, defined in a external library, to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString() and ReadKeyStroke() is a function on EFI_SIMPLE_TEXT_INPUT_PROTOCOL. They are available at interfaces pointed by ConIn and ConOut, at EFI_BOOT_SERVICES.

I strongly recommend to read UEFI specification (download, at least, version 2.7 - most BIOSes support this one). There you can find the entire documentation of how EFI works and how to use it in i386, x86-64, ARM, and other platforms.

The link you provided to the UEFI specifications doesn't work. Please fix your link.