Hi,
cool example, uefi using assembler, the example is written in Nasm, but I think it is easy to convert, this example can be run and tested on qemu :eusa_boohoo: https://github.com/charlesap/nasm-uefi/archive/master.zip (https://github.com/charlesap/nasm-uefi/archive/master.zip)
Quotebare-bones nasm uefi application
build with:
nasm -f bin yo.asm -o yo.efi
sudo mount uefi.iso /mnt
sudo cp yo.efi /mnt/
sudo umount /mnt
Launch QEMU with:
/usr/bin/qemu-system-x86_64 -machine accel=kvm -name guest=uefiguest -machine pc,accel=kvm,usb=off,dump-guest-core=off -smp 2,sockets=2,cores=1,threads=1 -uuid 515645b7-ab3a-4e82-ba62-25751e4b523f -bios ./OVMF.fd -m 1G -vga qxl -spice port=5900,addr=127.0.0.1,disable-ticketing -drive file=uefi.iso
Launch the Spice viewer with:
remote-viewer spice://localhost:5900
In the viewer, at the prompt enter 'fs0:'
Then enter 'yo'
bits 64
org 0x200000
section .header
DOS:
dd 0x00005a4d
times 14 dd 0
dd 0x00000080
times 16 dd 0
PECOFF:
dd `PE\0\0` ; sig
dw 0x8664 ; type
dw 3 ; sections
dd 0x5cba52f6 ; timestamp
dq 0 ; * symbol table + # symbols
dw osize ; oheader size
dw 0x202e ; characteristics
OHEADER:
dd 0x0000020b ; oheader + 0000 linker sig
dd 4096 ;codesize ; code size
dd 8192 ;datasize ; data size
dd 0 ; uninitialized data size
dd 4096 ; * entry
dd 4096 ; * code base
dq 0x200000 ; * image base
dd 4096 ; section alignment
dd 4096 ; file alignment
dq 0 ; os maj, min, image maj, min
dq 0 ; subsys maj, min, reserved
dd 0x4000 ; image size
dd 4096 ; headers size
dd 0 ; checksum
dd 0x0040000A ; dll characteristics & subsystem
dq 0x10000 ; stack reserve size
dq 0x10000 ; stack commit size
dq 0x10000 ; heap reserve size
dq 0 ; heap reserve commit
dd 0 ; loader flags
dd 0x10 ; rva count
DIRS:
times 5 dq 0 ; unused
dd 0x004000 ; virtual address .reloc
dd 0 ; size .reloc
times 10 dq 0 ; unused
OEND:
osize equ OEND - OHEADER
SECTS:
.1:
dq `.text` ; name
dd 4096 ;codesize ; virtual size
dd 4096 ; virtual address
dd 4096 ; raw data size
dd 4096 ; * raw data
dq 0 ; * relocations, * line numbers
dd 0 ; # relocations, # line numbers
dd 0x60000020 ; characteristics
.2:
dq `.data`
dd 8192 ;datasize
dd 8192
dd 8192
dd 8192
dq 0
dd 0
dd 0xC0000040
.3:
dq `.reloc`
dd 0
dd 0 ;20480
dd 0
dd 0 ;20480
dq 0
dd 0
dd 0x02000040
times 4096 - ($-$$) db 0 ;align the text section on a 4096 byte boundary
section .text follows=.header
EFI_SUCCESS equ 0
EFI_SYSTEM_TABLE_SIGNATURE equ 0x5453595320494249
EFI_SYSTEM_TABLE_CONOUT equ 64
EFI_SYSTEM_TABLE_RUNTIMESERVICES equ 88
EFI_SYSTEM_TABLE_BOOTSERVICES equ 96
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_RESET equ 0
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING equ 8
EFI_BOOT_SERVICES_GETMEMORYMAP equ 56
EFI_BOOT_SERVICES_LOCATEHANDLE equ 176
EFI_BOOT_SERVICES_LOADIMAGE equ 200
EFI_BOOT_SERVICES_EXIT equ 216
EFI_BOOT_SERVICES_EXITBOOTSERVICES equ 232
EFI_BOOT_SERVICES_LOCATEPROTOCOL equ 320
EFI_RUNTIME_SERVICES_RESETSYSTEM equ 104
sub rsp, 6*8
mov [Handle], rcx
mov [SystemTable], rdx
mov rax, [SystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE_BOOTSERVICES]
mov [BS], rax
mov rax, [SystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE_RUNTIMESERVICES]
mov [RTS], rax
lea rdx, [herewego]
mov rcx, [SystemTable]
mov rcx, [rcx + EFI_SYSTEM_TABLE_CONOUT]
call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
; get the memory map
mov qword [memmapsize], 4096
lea rcx, [memmapsize]
lea rdx, [memmap]
lea r8, [memmapkey]
lea r9, [memmapdescsize]
lea r10, [memmapdescver]
mov [STK],rsp
push r10
sub rsp, 4*8
mov rbx, [BS]
call [rbx + EFI_BOOT_SERVICES_GETMEMORYMAP]
add rsp, 4*8
pop r10
mov rsp, [STK]
cmp rax, EFI_SUCCESS
jne oops
; find the interface to GOP
mov rbx, [SystemTable]
mov rbx, [rbx + EFI_SYSTEM_TABLE_BOOTSERVICES]
mov rcx, _EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
mov rdx, 0
lea r8, [Interface]
call [rbx + EFI_BOOT_SERVICES_LOCATEPROTOCOL]
cmp rax, EFI_SUCCESS
jne oops
mov rcx, [Interface]
mov rcx, [rcx + 0x18 ] ;EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE
mov rbx, [rcx + 0x18 ] ;EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE_FRAMEBUFFERBASE
mov [FB], rbx
mov rcx, [rcx + 0x20 ] ;EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE_FRAMEBUFFERSIZE
mov [FBS], rcx
cmp rax, EFI_SUCCESS
jne oops
mov rbx, [FB]
push rax
push rcx
push rdx
call printhex
pop rdx
pop rcx
pop rax
mov rbx, [FBS]
push rax
push rcx
push rdx
call printhex
pop rdx
pop rcx
pop rax
; exit boot services
mov rcx, [Handle]
mov rdx, [memmapkey]
mov rbx, [SystemTable]
mov rbx, [rbx + EFI_SYSTEM_TABLE_BOOTSERVICES]
call [rbx + EFI_BOOT_SERVICES_EXITBOOTSERVICES]
cmp rax, EFI_SUCCESS
je g5
mov rbx, [memmapkey]
push rax
push rcx
push rdx
call printhex
pop rdx
pop rcx
pop rax
; repeat the call to get the memory map
mov qword [memmapsize], 4096
lea rcx, [memmapsize]
lea rdx, [memmap]
lea r8, [memmapkey]
lea r9, [memmapdescsize]
lea r10, [memmapdescver]
mov [STK],rsp
push r10
sub rsp, 4*8
mov rbx, [BS]
call [rbx + EFI_BOOT_SERVICES_GETMEMORYMAP]
add rsp, 4*8
pop r10
mov rsp, [STK]
cmp rax, EFI_SUCCESS
jne oops
mov rbx, [memmapkey]
push rax
push rcx
push rdx
call printhex
pop rdx
pop rcx
pop rax
; exit boot services again
mov rcx, [Handle]
mov rdx, [memmapkey]
xor r8, r8
mov rbx, [SystemTable]
mov rbx, [rbx + EFI_SYSTEM_TABLE_BOOTSERVICES]
call [rbx + EFI_BOOT_SERVICES_EXITBOOTSERVICES]
;cmp rax, EFI_SUCCESS
;je g5
;jmp oops
Z:
jmp Z
mov rcx, [FB]
mov rax, [FBS]
Q:
dec rax
mov byte[rcx+rax],255
jnz Q
W:
jmp W
g5:
mov rcx, 2 ;EfiResetShutdown
mov rdx, EFI_SUCCESS
mov rax, [SystemTable]
mov rax, [rax + EFI_SYSTEM_TABLE_RUNTIMESERVICES]
call [rax + EFI_RUNTIME_SERVICES_RESETSYSTEM]
oops:
lea rdx, [fail]
mov rcx, [SystemTable]
mov rcx, [rcx + EFI_SYSTEM_TABLE_CONOUT]
call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
jmp $-1
printhex:
mov rbp, 16
.loop:
rol rbx, 4
mov rax, rbx
and rax, 0Fh
lea rcx, [_Hex]
mov rax, [rax + rcx]
mov byte [_Num], al
lea rdx, [_Num]
mov rcx, [SystemTable]
mov rcx, [rcx + EFI_SYSTEM_TABLE_CONOUT]
call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
dec rbp
jnz .loop
lea rdx, [_Nl]
mov rcx, [SystemTable]
mov rcx, [rcx + EFI_SYSTEM_TABLE_CONOUT]
call [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
ret
times 8192-($-$$) db 0
codesize equ $ - $$
section .data follows=.text
Handle dq 0
SystemTable dq 0
Interface dq 0
BS dq 0
RTS dq 0
STK dq 0
FB dq 0
FBS dq 0
memmapsize dq 4096
memmapkey dq 0
memmapdescsize dq 48
memmapdescver dq 0
_EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID db 0xde, 0xa9, 0x42, 0x90, 0xdc, 0x23, 0x38, 0x4a
db 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a
fail db __utf16__ `fail.\r\n\0`
nok db __utf16__ `Not OK.\r\n\0`
yok db __utf16__ `OK.\r\n\0`
herewego db __utf16__ `here we go\r\n\0`
_Hex db '0123456789ABCDEF'
_Num dw 0,0
_Nl dw 13,10,0
times 4096-($-$$) db 0
memmap:
times 4096 db 0
datasize equ $ - $$
section .reloc follows=.data
So I got quite excited about playing with UEFI again.. So for UASM 2.50 release I've created a new custom EFI.INC with all the type/structs hand ported from the C headers.. I will be making a tutorial for it explaining in detail how to setup UEFI and get it booting on real h/w, Virtual BOX etc with a simple build and debug process for creating UEFI apps and boot files.. Just to give you an example of how the header port works in UASM (a lot nicer than NASM ;) )
OPTION WIN64:15
OPTION STACKBASE:RSP
OPTION LITERALS:ON
OPTION ARCH:AVX
OPTION CASEMAP:NONE
include efi.inc
.data
Handle dq 0
SystemTablePtr dq 0
HelloMsg dw 'Hello UEFI World!',13,10,0
pConsole PCONOUT 0
pBootServices P_BOOT_SERVICES 0
mapSize UINTN 64*SIZEOF(EFI_MEMORY_DESCRIPTOR)
descriptors EFI_MEMORY_DESCRIPTOR 64 DUP (<?>)
mapKey UINTN 0
descSize UINTN 0
descVer UINT32 0
.code
Main PROC FRAME imageHandle:EFI_HANDLE, SystemTable:PTR_EFI_SYSTEM_TABLE
mov Handle,rcx
mov SystemTablePtr,rdx
;=====================================================================================
; The normal ASM way to make a 64bit FASTCALL.
;=====================================================================================
sub rsp,20h
lea rdx,HelloMsg
mov rcx,SystemTablePtr
mov rcx,[rcx + EFI_SYSTEM_TABLE_CONOUT]
call qword ptr [rcx + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_OUTPUTSTRING]
add rsp,20h
;=====================================================================================
; The smarter UASM way...
;=====================================================================================
mov rcx,SystemTablePtr
mov rcx,[rcx].EFI_SYSTEM_TABLE.ConOut
mov pConsole,rcx
invoke [rcx].ConOut.OutputString, pConsole, L"Hello Smarter UEFI World!\r\n"
; Or if you have a list of calls to make against the same protocol/interface
ASSUME rcx:PTR ConOut
mov rcx,pConsole
invoke [rcx].OutputString, pConsole, ADDR HelloMsg
ASSUME rcx:NOTHING
;=====================================================================================
; The even smarter ways...
;=====================================================================================
pConsole->OutputString(pConsole, L"Testing\r\n")
; or
mov rax,pConsole
[rax].ConOut->OutputString(pConsole, L"Testing2\r\n")
pConsole->ClearScreen()
;=====================================================================================
; Store pointer to the BOOT SERVICES Interface
;=====================================================================================
mov rax,SystemTablePtr
mov rsi,[rax].EFI_SYSTEM_TABLE.BootServices
mov pBootServices,rsi
; Get Memory Map
[rsi].BOOT_SERVICES->GetMemoryMap(&mapSize, &descriptors, &mapKey, &descSize, &descVer)
.if(rax != EFI_SUCCESS)
pConsole->OutputString(pConsole, L"Failed to get memory map\r\n")
pBootServices->Exit(Handle, EFI_ERROR, 36, L"Memory Map Error\r\n")
.else
pConsole->OutputString(pConsole, L"Got memory map\r\n")
.endif
mov eax,EFI_SUCCESS
ret
Main ENDP
END Main
Busy adding in the GOP protocol now, curious to see how raw framebuffer access performs under UEFI as previously I had quite good performance from a VBE frame-buffer in a raw 64bit OS setup as long as the buffer was mapped write-combining.
Hi,
The includes, library examples and guide are now complete and available on the website. Please note this only works with UASM 2.50 which will be available soon as binary packages. In the meantime the 2.50 branch is available in Github.
Please let me know if you have any reports or questions and happy UEFI coding in UASM! :) (I know I have been)
John
I am not seeing
RAWINTERFACE
ENDRAWINTERFACE
STDFUNC
defined anywhere.
(https://www.dropbox.com/s/hxa32yuvjm3lhyx/uasm250.jpg?dl=1)
My bad, I'd forgotten to push the repo changes. They're in 2.50 branch now along with a few missing return values pointed out by TimoVJL.
I have two more fixes to add and then it should be ready.
uasm 2.50 :undecided:
\masm32\m32lib\a2wc.asm(14) : Error A2143: Symbol redefinition: memalign
...
memalign is a built-in macro, did that source compile before ?
an old masm32 sources and older versions works.
An option would be to compile the source using the no macro lib switch ?
The change is possibly that I've added some more case insensitive options to the macrolib IE MEMALIGN vs memalign.
DELETED
; empty line
.x64p
OPTION WIN64:15
OPTION STACKBASE:RSP
OPTION LITERALS:ON
OPTION ARCH:AVX ; <- Builds if removed
OPTION CASEMAP:NONE
(https://www.dropbox.com/s/0i4wm5kcqjhq17a/uasm250b.jpg?dl=1)
That's odd, I can't reproduce that error here. Is that the exact hello.asm file from the package ?
Quote from: johnsa on October 20, 2019, 02:22:07 AM
That's odd, I can't reproduce that error here. Is that the exact hello.asm file from the package ?
It is the UEFI hello.asm from your website. I tested in 2 different computers, in 2 different OSs and with 2 builds of UASM-64 (VS 2019 and the Timo's (Pelles)).
:sad:
Quote from: TimoVJL on October 20, 2019, 07:20:15 AM
EDIT: small fix for AVX option.
Not yet.
efiUtil.inc(89) : Error A2295: Invalid use of pointer operator
efiUtil.inc(89): Included by
hello.asm(27): Main line code
efiUtil.inc(89) : Error A2169: General Failure
efiUtil.inc(89): Included by
hello.asm(27): Main line code
here :undecided:
C:\code\UAsm\UASM_Uefi>uasm64 -c -win64 -Zp8 hello.asm
UASM v2.50, Oct 19 2019, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
hello.asm: 106 lines, 4 passes, 18 ms, 0 warnings, 0 errors
options.c line 178 if (0 == _stricmp(tokenarray[i].string_ptr, "SSE")) {
MODULEARCH = ARCH_SSE;
ModuleInfo.arch = ARCH_SSE;
/* strcpy(MOVE_ALIGNED_FLOAT, "movaps");
strcpy(MOVE_ALIGNED_INT, "movdqa");
strcpy(MOVE_UNALIGNED_FLOAT, "movups");
strcpy(MOVE_UNALIGNED_INT, "movdqu");
strcpy(MOVE_SINGLE, "movss");
strcpy(MOVE_DOUBLE, "movsd");
strcpy(MOVE_SIMD_DWORD, "movd");
strcpy(MOVE_SIMD_QWORD, "movq");*/
MOVE_ALIGNED_FLOAT = "movaps";
MOVE_ALIGNED_INT = "movdqa";
MOVE_UNALIGNED_FLOAT = "movups";
MOVE_UNALIGNED_INT = "movdqu";
MOVE_SINGLE = "movss";
MOVE_DOUBLE = "movsd";
MOVE_SIMD_DWORD = "movd";
MOVE_SIMD_QWORD = "movq";
archSym->value = ARCH_SSE;
}
else if (0 == _stricmp(tokenarray[i].string_ptr, "AVX")) {
MODULEARCH = ARCH_AVX;
ModuleInfo.arch = ARCH_AVX;
/* strcpy(MOVE_ALIGNED_FLOAT, "vmovaps");
strcpy(MOVE_ALIGNED_INT, "vmovdqa");
strcpy(MOVE_UNALIGNED_FLOAT, "vmovups");
strcpy(MOVE_UNALIGNED_INT, "vmovdqu");
strcpy(MOVE_SINGLE, "vmovss");
strcpy(MOVE_DOUBLE, "vmovsd");
strcpy(MOVE_SIMD_DWORD, "vmovd");
strcpy(MOVE_SIMD_QWORD, "vmovq");*/
MOVE_ALIGNED_FLOAT = "vmovaps";
MOVE_ALIGNED_INT = "vmovdqa";
MOVE_UNALIGNED_FLOAT = "vmovups";
MOVE_UNALIGNED_INT = "vmovdqu";
MOVE_SINGLE = "vmovss";
MOVE_DOUBLE = "vmovsd";
MOVE_SIMD_DWORD = "vmovd";
MOVE_SIMD_QWORD = "vmovq";
archSym->value = ARCH_AVX;
}
Sometimes builds other times not, depends on the alignment, corrupted memory or something.
Given the definitions of:
/* ARCH SSE/AVX specific instructions */
char *MOVE_ALIGNED_FLOAT = "movaps";
char *MOVE_ALIGNED_INT = "movdqa";
char *MOVE_UNALIGNED_FLOAT = "movups";
char *MOVE_UNALIGNED_INT = "movdqu";
char *MOVE_SINGLE = "movss";
char *MOVE_DOUBLE = "movsd";
char *MOVE_SIMD_DWORD = "movd";
char *MOVE_SIMD_QWORD = "movq";
There is something odd on the strcpy we see.
:sad:
Initializing the char pointers as an array solved for me, because we are not writing to CONST as before (ex: strcpy(MOVE_ALIGNED_FLOAT, "movaps");), which is illegal. However we have to bear in mind that the AVX instructions have more one character than the SSE and the array (as well as the char pointer before) were initialized for SSE. This means there is a risk of memory corruption.
So in assemble.c:
char MOVE_ALIGNED_FLOAT[] = "movaps";
char MOVE_ALIGNED_INT[] = "movdqa";
char MOVE_UNALIGNED_FLOAT[] = "movups";
char MOVE_UNALIGNED_INT[] = "movdqu";
char MOVE_SINGLE[] = "movss";
char MOVE_DOUBLE[] = "movsd";
char MOVE_SIMD_DWORD[] = "movd";
char MOVE_SIMD_QWORD[] = "movq";
and in globals.h
extern char MOVE_ALIGNED_FLOAT[];
extern char MOVE_ALIGNED_INT[];
extern char MOVE_UNALIGNED_FLOAT[];
extern char MOVE_UNALIGNED_INT[];
extern char MOVE_SINGLE[];
extern char MOVE_DOUBLE[];
extern char MOVE_SIMD_DWORD[];
extern char MOVE_SIMD_QWORD[];
or a volatile pointers to avoid unnecessary copying ?/* global strings for arch:sse/avx instructions to use */
extern volatile char *MOVE_ALIGNED_FLOAT;
extern volatile char *MOVE_ALIGNED_INT;
extern volatile char *MOVE_UNALIGNED_FLOAT;
extern volatile char *MOVE_UNALIGNED_INT;
extern volatile char *MOVE_SINGLE;
extern volatile char *MOVE_DOUBLE;
extern volatile char *MOVE_SIMD_DWORD;
extern volatile char *MOVE_SIMD_QWORD;
How-To use C volatile keyword (https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword)
and cmdline.c needs a fix too
static void OPTQUAL Set_SSE(void)
{
ModuleInfo.arch = ARCH_SSE;
MODULEARCH = ARCH_SSE;
MOVE_ALIGNED_FLOAT = "movaps";
MOVE_ALIGNED_INT = "movdqa";
MOVE_UNALIGNED_FLOAT = "movups";
MOVE_UNALIGNED_INT = "movdqu";
MOVE_SINGLE = "movss";
MOVE_DOUBLE = "movsd";
MOVE_SIMD_DWORD = "movd";
MOVE_SIMD_QWORD = "movq";
}
static void OPTQUAL Set_AVX(void)
{
ModuleInfo.arch = ARCH_AVX;
MODULEARCH = ARCH_AVX;
MOVE_ALIGNED_FLOAT = "vmovaps";
MOVE_ALIGNED_INT = "vmovdqa";
MOVE_UNALIGNED_FLOAT = "vmovups";
MOVE_UNALIGNED_INT = "vmovdqu";
MOVE_SINGLE = "vmovss";
MOVE_DOUBLE, "vmovsd";
MOVE_SIMD_DWORD = "vmovd";
MOVE_SIMD_QWORD = "vmovq";
}
Seeing this situation further some of the symbol's object's are inconsistent between call, and don'ts get assigned for AVX.
Maybe something like this, to make the symbol consistent with ARCH option between the used calls.
globals.h
extern const char* MOVE_ALIGNED_FLOAT();
extern const char* MOVE_ALIGNED_INT();
extern const char* MOVE_UNALIGNED_FLOAT();
extern const char* MOVE_UNALIGNED_INT();
extern const char* MOVE_SINGLE();
extern const char* MOVE_DOUBLE();
extern const char* MOVE_SIMD_DWORD();
extern const char* MOVE_SIMD_QWORD();
assemble.c
/* ARCH SSE/AVX specific instructions */
const char* MOVE_ALIGNED_FLOAT()
{
if (MODULEARCH == ARCH_AVX) return "vmovaps"; else return "movaps";
}
const char* MOVE_ALIGNED_INT()
{
if (MODULEARCH == ARCH_AVX) return "vmovdqa"; else return "movdqa";
}
const char* MOVE_UNALIGNED_FLOAT()
{
if (MODULEARCH == ARCH_AVX) return "vmovups"; else return "movups";
}
const char* MOVE_UNALIGNED_INT()
{
if (MODULEARCH == ARCH_AVX) return "vmovdqu"; else return "movdqu";
}
const char* MOVE_SINGLE()
{
if (MODULEARCH == ARCH_AVX) return "vmovss"; else return "movss";
}
const char* MOVE_DOUBLE()
{
if (MODULEARCH == ARCH_AVX) return "vmovsd"; else return "movsd";
}
const char* MOVE_SIMD_DWORD()
{
if (MODULEARCH == ARCH_AVX) return "vmovd"; else return "movd";
}
const char* MOVE_SIMD_QWORD()
{
if (MODULEARCH == ARCH_AVX) return "vmovq"; else return "movq";
}
cmdline.c
in
Set_AVX remove all instances strcpy(MOVE_?, "?")
Set_SSE remove all instances strcpy(MOVE_?, "?")
expreval.c
strcpy(buffer1, MOVE_UNALIGNED_FLOAT); to strcpy(buffer1, MOVE_UNALIGNED_FLOAT());
options.c
in
SetArch remove all instances strcpy(MOVE_?, "?")
invoke.c
change all instances MOVE_? to MOVE_?()
proc.c
change all instances MOVE_? to MOVE_?()
I like the improved consistency of those calls, let me make the same on the 2.50 branch.
.x64p
OPTION WIN64:15
OPTION STACKBASE:RSP
OPTION LITERALS:ON
;OPTION ARCH:AVX
OPTION CASEMAP:NONE
include efi.inc
include efiUtil.inc
END
UASM v2.50, Oct 20 2019, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
efiUtil.inc(89) : Error A2295: Invalid use of pointer operator
efiUtil.inc(89): Included by
efi_foo1.asm(9): Main line code
efiUtil.inc(89) : Error A2169: General Failure
efiUtil.inc(89): Included by
efi_foo1.asm(9): Main line code
*** Process returned 1 ***
let me know, if msvc version don't give these errors, that i have in C99 version.
.x64p
OPTION WIN64:15
OPTION STACKBASE:RSP
OPTION LITERALS:ON
;OPTION ARCH:AVX
OPTION CASEMAP:NONE
include efi.inc
;include efiUtil.inc
.data
hexSTR dw 20 DUP (0)
.code
foo PROC FRAME pConsoleOut:PCONOUT
pConsole->OutputString(pConsole, &hexSTR)
ret
foo ENDP
END
the MSVC version of 2.50 branch with the changes for avx/sse const strings isn't giving me any errors.
deleted
I obtain the same errors as Timo when building with VS2019 with the changes proposed by KradMoonRa.
But this appears to be unrelated with the current issue.
I've put a binary I've built now on the site, please try that:
www.terraspace.co.uk/uasm250_x64.zip (http://www.terraspace.co.uk/uasm250_x64.zip)
www.terraspace.co.uk/uasm250_x86.zip (http://www.terraspace.co.uk/uasm250_x86.zip)
Yes, it works.
Also Clang compiled version using volatile works.
http://masm32.com/board/index.php?topic=7942.msg89132#msg89132
Error A2143: Symbol redefinition: memalign (and I never use this symbol)
include \masm32\include\masm32rt.inc ; plain Masm32 for the fans of pure assembler
.code
AppName db "Masm32:", 0
start: MsgBox 0, "Hello World, how are you?", addr AppName, MB_OK
exit
end start
Confirmed it's working, successfully builds UASM_uefi hello example.
AW thanks for pointing that the proposed version has other problems. I have dig in the code and found that the macros has serious problems, and like the convention aren't applied in prototypes by default. Fixed and cleaned up.
In assembly code the new adopted names can conflict and flagged has symbol redefinition.
IFNDEF INT8
INT8 TYPEDEF BYTE
ENDIF
IFNDEF UINT8
UINT8 TYPEDEF BYTE
ENDIF
IFNDEF INT16
INT16 TYPEDEF WORD
ENDIF
IFNDEF UINT16
UINT16 TYPEDEF WORD
ENDIF
IFNDEF INT32
INT32 TYPEDEF DWORD
ENDIF
IFNDEF UINT32
UINT32 TYPEDEF DWORD
ENDIF
IFNDEF INT64
INT64 TYPEDEF QWORD
ENDIF
IFNDEF UINT64
UINT64 TYPEDEF QWORD
ENDIF
;in C:\masm32\macros\macros.asm
IFNDEF memalign
memalign MACRO reg, number
add reg, number - 1
and reg, -number
ENDM
ENDIF
You found a workaround, KradMoonRa :thumbsup:
But having to edit standard Masm32 files is a major nuisance. Habran & Johnsa, please correct this name conflict.
;in C:\masm32\macros\macros.asm
IFNDEF memalign
memalign MACRO reg, number
add reg, number - 1
and reg, -number
ENDM
ENDIF
The supplied distributions, I have only tested the 64-bit one, work for the hello.asm sample. Any other solution, other than the KradMoonRa's, that would not write to the CONST section was going to work as well as has been seen before.
However, the binary does not fix the bug mentioned here (http://masm32.com/board/index.php?topic=7942.msg89136#msg89136) which is of a different nature. It does not fix as well the Masm32 incompatibility mentioned here (http://masm32.com/board/index.php?topic=7942.msg89097#msg89097) (which was later rediscovered by JJ while assembling his fat Basic sources).
The Windows 10 x64 mystery wasn't solved, more code just hides it.
PS: this should work too:
global.h
/* global strings for arch:sse/avx instructions to use */
extern char *MOVE_ALIGNED_FLOAT;
extern char *MOVE_ALIGNED_INT;
extern char *MOVE_UNALIGNED_FLOAT;
extern char *MOVE_UNALIGNED_INT;
extern char *MOVE_SINGLE;
extern char *MOVE_DOUBLE;
extern char *MOVE_SIMD_DWORD;
extern char *MOVE_SIMD_QWORD;
assemble.c/* ARCH SSE/AVX specific instructions */
char *MOVE_ALIGNED_FLOAT; // = "movaps";
char *MOVE_ALIGNED_INT; // = "movdqa";
char *MOVE_UNALIGNED_FLOAT; // = "movups";
char *MOVE_UNALIGNED_INT; // = "movdqu";
char *MOVE_SINGLE; // = "movss";
char *MOVE_DOUBLE; // = "movsd";
char *MOVE_SIMD_DWORD; // = "movd";
char *MOVE_SIMD_QWORD; // = "movq";
option.c if (tokenarray[i].token == T_ID) {
if (0 == _stricmp(tokenarray[i].string_ptr, "SSE")) {
MODULEARCH = ARCH_SSE;
ModuleInfo.arch = ARCH_SSE;
MOVE_ALIGNED_FLOAT = "movaps";
MOVE_ALIGNED_INT = "movdqa";
MOVE_UNALIGNED_FLOAT = "movups";
MOVE_UNALIGNED_INT = "movdqu";
MOVE_SINGLE = "movss";
MOVE_DOUBLE = "movsd";
MOVE_SIMD_DWORD = "movd";
MOVE_SIMD_QWORD = "movq";
archSym->value = ARCH_SSE;
}
else if (0 == _stricmp(tokenarray[i].string_ptr, "AVX")) {
MODULEARCH = ARCH_AVX;
ModuleInfo.arch = ARCH_AVX;
MOVE_ALIGNED_FLOAT = "vmovaps";
MOVE_ALIGNED_INT = "vmovdqa";
MOVE_UNALIGNED_FLOAT = "vmovups";
MOVE_UNALIGNED_INT = "vmovdqu";
MOVE_SINGLE = "vmovss";
MOVE_DOUBLE = "vmovsd";
MOVE_SIMD_DWORD = "vmovd";
MOVE_SIMD_QWORD = "vmovq";
archSym->value = ARCH_AVX;
}
those pointers are set for SSE / AVX only when needed.
Quote from: johnsa on October 19, 2019, 09:24:35 AM
memalign is a built-in macro, did that source compile before ?
Yes. Now even the simplest Masm32 hello world chokes. You have a name conflict, please change the name of the built-in macro.
Btw this is another proof that built-in macros are a problem rather than a feature: The Masm32 memalign in macros.asm works just fine. MASM uses things like @InStr() and @CatStr() for its handful of built-in macros, maybe @MemAlign would be an option?
include \masm32\include\masm32rt.inc ; plain Masm32 for the fans of pure assembler
.code
AppName db "Masm32:", 0
start: MsgBox 0, "Hello World, how are you?", addr AppName, MB_OK
exit
end start
I have seen this problem before long ago, when you have a MACRO assembler, you can extend it in many ways by using the pre-processor and doing simple macros like memory alignment is one of the more trivial tasks but it also means that the assembler does not have to try and emulate simple things that its pre-processor can routinely do.
Years ago Betov, the author of SpAsm tried to ape some of the routine masm macros but without a decent pre-processor, it flopped. Only Guga is brave enough to try and solve Betov's design problems. To each their design philosophy but if an assembler is to be MASM compatible, it will not exclude the basic MASM pre-processor capacity.
What I would suggest is abandon emulating MASM macros and if anything needs to be improved, fix the pre-processor so it is more consistent than the old MASM version. There is no reason why UASM cannot have its own set of macros which can be modified, added to or replaced, then it will be a properly extendable tool. Going down the path of trying to emulate a C compiler is a mistake, there are plenty of competent C compilers already.
maybe an option switch for every additional features.
Independently of the arguments presented, which are pertinent as well, something I don't understand is the reason the MEMALIGN macro that exists in UASM for so many years only now is causing issues. Why is UASM considering "memalign" (which is the Masm32 version) the same as "MEMALIGN" (the UASM version)?
macrolib.c line 170
AddLineQueue("memalign EQU MEMALIGN");
Quote from: TimoVJL on October 21, 2019, 07:57:56 PM
maybe an option switch for every additional features.
Right - and "on" should
not be the default. Even when the features are "on", they should not break the entirety of the accumulated Masm32 sources imho.
AsmC has a similar problem: many sources won't run without the
/Zne option to disable non-Masm extensions. The whole point of compatibility is that 90% of all sources have been written for MASM. If you need to explain to a coder that in order to use the xyz assembler you need to teach your IDE to use the xyz command line options, you've lost that compatibility game, fullstop.
I had flagged the memalign issue in another thread (http://masm32.com/board/index.php?topic=8044.msg89141#msg89141) but the post is no longer there :sad:
Quote from: TimoVJL on October 21, 2019, 08:52:50 PM
macrolib.c line 170
AddLineQueue("memalign EQU MEMALIGN");
Yeah, UASM is doing this for a selected and small number of macros, but the only one that appears to collide with Masm32 is the memalign. :badgrin:
Some people here are confusing Masm with Masm32, Masm32 is an add-on SDK not developed and not endorsed by Microsoft.
In this last release I added a case insensitive equ for memalign, which is why it is now colliding with the masm32 lib version.
I'm happy to remove the case sensitive version for this or rename it.. we can take a vote.
Personally I'd opt to rename it so that the case can be freely applied.
The internal macro library can be shut off by: -nomlib Disable internal Macro Library
OR.
Can be selected all conflicting names and integrated separate -useadvmlib to use the new macro names, and still use the macros no conflicting.
using something like
.asm
options:nomlib ;shutoff all macrolib inclusive the new ones
;or and
otions:useadvmlib ;use the new included macros
Quote from: johnsa on October 21, 2019, 09:54:07 PMPersonally I'd opt to rename it so that the case can be freely applied.
I'd vote to name internal macros MASM style, like @CatStr(), @Instr(), so @MemAlign would be most consistent.
Quote from: AW on October 21, 2019, 09:17:04 PM
UASM is doing this for a selected and small number of macros, but the only one that appears to collide with Masm32 is the memalign
Indeed. I wonder why
memalign chokes while fld
FP8(2.0) doesn't :rolleyes:
There is another little problem:
include \masm32\include\masm32rt.inc ; plain Masm32 for the fans of pure assembler
.586
.xmm
.code
AppName db "Masm32:", 0
start: MsgBox 0, "Hello World, how are you?", addr AppName, MB_OK
fld FP8(2.0)
Movss xmm0, FP4(2.3)
exit
end start
Fine for ML 6.14 but UAsm chokes with
Error A2030: Instruction or register not accepted in current CPU modeQuote from: AW on October 21, 2019, 09:17:04 PMSome people here are confusing Masm with Masm32, Masm32 is an add-on SDK not developed and not endorsed by Microsoft.
Absolutely nobody would use MASM nowadays, had there not been the Masm32 SDK. It is the de facto standard for doing anything useful in assembly, at least for 32-bit code. And breaking its huge codebase is not a good idea.
Quote from: jj2007 on October 21, 2019, 10:22:08 PM
Absolutely nobody would use MASM nowadays, had there not been the Masm32 SDK. It is the de facto standard for doing anything useful in assembly, at least for 32-bit code. And breaking its huge codebase is not a good idea.
Actually MASM is taught in college and high-school and Masm32 is not allowed there. Device Driver developers sometimes use Masm, and obviously can't use Masm32 for device drivers.
Very few people use Masm32, even here most people is more concerned with lateral matters than any sort of programming.
But Masm32 is a very valuable SDK, both 32-bit and 64-bit.
You need to use at least .686 to allow the simd instructions, at least it's always been this way in jwasm/uasm. .686 should then work for both uasm and masm.
I've changed MEMALIGN to ALIGNADDR .. makes sense and it shouldn't conflict with anything.
Updated the packages on the site.
Quote from: johnsa on October 21, 2019, 09:54:07 PM
I'm happy to remove the case sensitive version for this or rename it.. we can take a vote.
Personally I'd opt to rename it so that the case can be freely applied.
I don't know if this makes sense, but the assembler could simply supersede any internal macro whenever there is a user defined macro with the same name. This will prevent the need for another switch which people tend to forget (and UASM already has a large number of them to remember).
Agreed, for now I'm going to leave it renamed so there is no immediate conflict.
I think in future I will add a flag to the definitions of the macro-lib marking them as "internal", so that we can override them with any user defined ones.
:biggrin:
> Actually MASM is taught in college and high-school and Masm32 is not allowed there.
You may be surprised just how many UNI courses use the MASM32 SDK and over how many years. Where MASM is taught at universities, it is usually DOS 16 bit and others use Kip Irvine's book and examples.
Quote from: hutch-- on October 21, 2019, 11:29:56 PM
:biggrin:
You may be surprised just how many UNI courses use the MASM32 SDK and over how many years. Where MASM is taught at universities, it is usually DOS 16 bit and others use Kip Irvine's book and examples.
:biggrin:
Bad luck, when I was doing online tutoring not a single one requested Masm32. For x86/x64 ASM, all of them required Irvine for 16, 32 and 64-bit.
:biggrin:
Bigger fool them, commerce dictates BUYING the software. :tongue:
Quote from: AW on October 21, 2019, 11:46:23 PM
Bad luck, when I was doing online tutoring not a single one requested Masm32.
Then: MASM32 is very easy. :biggrin:
I suspect teachers were receiving a fat commission for doing classes based on the Irvine's book. :badgrin:
:sad:
Quote from: johnsa on October 21, 2019, 10:59:27 PM
You need to use at least .686 to allow the simd instructions, at least it's always been this way in jwasm/uasm. .686 should then work for both uasm and masm.
I've changed MEMALIGN to ALIGNADDR .. makes sense and it shouldn't conflict with anything.
Updated the packages on the site.
Hi johnsa,
I updated the cache, but the links are old :icon_idea:
I've only updated the packages not the site, just waiting for confirmation that initial testing was ok.
John,
Where is the latest UAsm64.exe? The one with the memalign problem is 20 Oct 20:50.
:sad:
Quote from: TimoVJL on October 22, 2019, 05:49:12 PM
UAsm 2.50 compiled with Clang 9 and using msvcrt.dll, so it's so slow.
Now it works, but it's indeed not that fast:
1750 ms Uasm64msvcrt, ML 6.15 & 10.0
1500 ms Uasm64
1150 ms AsmC
clang 9 & libc
5.382s asmc.exe 2.30.23
7.831s uasm64libc.exe 2.50
8.393s uasm64vc2019.exe 2.50
8.830s uasm64.exe 2.49
9.235s uasm64poc9.exe 2.50
10.124s uasm32libc.exe 2.50
EDIT: fix WIN64
It works, Timo :thumbsup:
1750 ms Uasm64msvcrt, ML 6.15 & 10.0
1500 ms Uasm64
1400 ms Uasm64libc
1150 ms AsmC
I get a general failure using this libc version on some of my test pieces
:sad:
:sad:
I turned the internal macros into external MACROS (see below) to debug better, but the error is not related to the macros, as I thought initially. I.e, the internal macros are good.
The error will disappear if we uncomment the line 'pConsole PCONOUT 0' (see below), i.e the origin of the error 'Invalid use of pointer operator' is tracked and makes sense:
.x64p
OPTION WIN64:15
OPTION STACKBASE:Rsp
OPTION LITERALS:ON
OPTION ARCH:AVX
OPTION CASEMAP:NONE
RAWINTERFACE MACRO CName:REQ
curClass TEXTEQU <CName>
% __&CName&_size = 0
@CatStr(CName, < RAWSTRUCT >)
ptrDefS TEXTEQU <psr>
ptrDefS CATSTR ptrDefS, <&curClass&>, < TYPEDEF PTR >, <&curClass&>
% ptrDefS
;% echo _ptrDefS= ptrDefS
ENDM
ENDRAWINTERFACE MACRO
curClass ENDS
.data
% _stat&curClass& curClass <>
ENDM
STDFUNC MACRO method:REQ, retType:REQ, protoDef:VARARG
LOCAL sz1, sz2
pDef CATSTR <TYPEDEF PROTO >,<(&retType&) >
;% echo _pedef= pDef
IFNB <protoDef>
pDef CATSTR pDef, <, >, <&protoDef>
ENDIF
sz2 CATSTR <_>, curClass, <_&method>, <Pto>
% &sz2 &pDef
% sz1 typedef PTR &sz2
% method sz1 0
% __&curClass&_size = __&curClass&_size + 8
fnex TEXTEQU <_>
fnex CATSTR fnex, curClass, <_>, <&method&>, < PROTO >, <(&retType&) >
IFNB <&protoDef>
fnex CATSTR fnex, <, >, <&protoDef&>
ELSE
ENDIF
fnex
; % echo _fnex= fnex
ENDM
CHAR16 TYPEDEF WORD
P_CHAR16 TYPEDEF PTR CHAR16
RAWINTERFACE ConOut
STDFUNC OutputString, <voidarg>, pThis:PTR _ConOut, pStr:P_CHAR16
ENDRAWINTERFACE
PCONOUT TYPEDEF PTR ConOut
.data
;pConsole PCONOUT 0 ; If we uncomment NO error
hexSTR dw 20 DUP (0)
.code
main PROC FRAME pConsoleOut:PCONOUT
pConsole->OutputString(pConsole, &hexSTR)
ret
main ENDP
END
Works fine but AsmC is a tick faster (1400 vs 1050 ms for 21k lines test case) :thumbsup:
Why: no site interest, so i save site space :sad:
Experts should fix obvious things, so why i bother :undecided:
I've applied Timo's fixes in 2.50 branch now as well and can confirm it solves the bug AW showed last. A proper error is now reporting when pConsole is not defined, and assembly completes as expected when it is defined.
gcc and clang compiles it OK :thumbsup:
Hi johnsa!
Efi.inc line 758 must be:
RAWINTERFACE EFI_BOOT_SERVICES
Regards, HSE.
Quote from: HSE on April 07, 2022, 04:00:54 AM
Efi.inc line 758 must be:
RAWINTERFACE EFI_BOOT_SERVICES
Good find! :thumbsup:
Hi Gunther!
Quote from: Gunther on April 07, 2022, 03:17:30 PM
Good find! :thumbsup:
A couple of weeks ago I maked a FreeDos USB because I found a Chourdakis work that allow to make FreeDos multicore, and can be interesting to test if some big simulations can run faster with more machine control. Happen that FreeDos rely on BIOS, and new machines with Intel chips only have UEFI :biggrin:
Now I'm playing with very simple things. But perhaps is not so dificult to make a like-microOS program, just because a UEFI machine boot from an almost standard windows PE64 file using the X64 calling convention we know.
Regards, HSE.
Hi! again :biggrin:
There is some problem close to Efi.inc line 324:
; *******************************************************
; EFI_FILE_PROTOCOL
; *******************************************************
RAWINTERFACE EFI_FILE_HANDLE
Not sure what the problem is, anyway that must be:
; *******************************************************
; EFI_FILE_PROTOCOL
; *******************************************************
RAWINTERFACE EFI_FILE_PROTOCOL
HSE,
Quote from: HSE on April 16, 2022, 08:50:50 AM
Hi! again :biggrin:
There is some problem close to Efi.inc line 324:
; *******************************************************
; EFI_FILE_PROTOCOL
; *******************************************************
RAWINTERFACE EFI_FILE_HANDLE
Not sure what the problem is, anyway that must be:
; *******************************************************
; EFI_FILE_PROTOCOL
; *******************************************************
RAWINTERFACE EFI_FILE_PROTOCOL
I always notice: You're very aware. Thanks for that. :thumbsup:
Hi Gunther!
Quote from: Gunther on April 16, 2022, 09:10:12 AM
I always notice: You're very aware. Thanks for that. :thumbsup:
Are you just following the subject, or building some UEFI application?
HSE,
Quote from: HSE on April 16, 2022, 09:28:12 AM
Are you just following the subject, or building some UEFI application?
Both. The subject is important if UEFI applications are planned. With Intel's design decision, we've now the whole thing on our hands. There are alternatives,
but they are still in their early stages.
:thumbsup:
HSE,
what is your goal? Do you just want to fix errors in Efi.inc?
Gunther,
Quote from: Gunther on April 16, 2022, 11:33:57 PM
what is your goal? Do you just want to fix errors in Efi.inc?
Combine here (http://masm32.com/board/index.php?topic=7942.msg109335#msg109335) and here (http://masm32.com/board/index.php?topic=9981.msg109380#msg109380).
So far, I don't found any small UEFI OS, all are from BIOS era, wich now begin to fade (and my PC don't run legacy BIOS :biggrin:). If you know some small UEFI OS, I will preciate that data.
First point is to prove that big simulations can run without any OS in UEFI machines. That can not be dificult because ObjAsm have optimized functions, then need very few things from OS for calculations.
Second point is to test if this simulations can run faster than inside Win OS.
Quote from: HSE on April 17, 2022, 12:52:46 AMSecond point is to test if this simulations can run faster than inside Win OS.
Yeah, Windows slows down everything. Oh, wait: task manager says cpu use is 2%, with 80+ processes running. How could an application run faster in another OS, if 98% of the cpu are available? What's the theory behind the assumption that, for example, Linux runs your stuff faster than Windows? Just curious :cool:
P.S.: There is a wealth of evidence here (https://openbenchmarking.org/result/2107013-IB-WIN11LINU39).
I specifically built the UEFI stuff for just this reason.. for my personal OS project work. I had a small toy-OS running on a bunch of PCs, even working on an x86 mac pro.
I can tell you a few things, you'd be surprised at how little difference running that bare metal actually makes over Windows 10. As a test I wrote a distance-marching software renderer, running from my bare long-mode UEFI OS vs. Windows showed about a 10% performance gain.
To even get that took a lot of work making a set of drivers of AMD and NVidia gfx cards, not actually mode-setting, I relied on UEFI graphics to set the mode, but what you need to do is ensure you have the framebuffer memory configured as write-combining in the MTRRs and or PAT, and even more importantly, using UEFI PCI tools you can see that when you run under Windows the video card is set to maximum transfer rate via PCIe config but not from clean boot. It took a bunch of digging in the little docs that are available as well as pinging some of the guys from the Noveau driver project to find the right PCI BAR config regs to get that setup. With that in place, you can software fill 1920x1080x32bit framebuffer and actually get it to the GPU at well over 1000 fps (as a baseline).
I went on to write an HD Audio driver so I had some sound playing too.. it was all good fun.. but at the end of the day.. I'm not sure it's worth it for 10% (If Windows slowed the code down by 30+ percent.. then yeah). I'll share the code for the bits of it if you like, just PM me.
Hi JJ!
Quote from: jj2007 on April 17, 2022, 02:03:51 AM
How could an application run faster in another OS, if 98% of the cpu are available?
100%
Quote from: jj2007 on April 17, 2022, 02:03:51 AM
What's the theory behind the assumption that, for example, Linux runs your stuff faster than Windows? Just curious :cool:
Linux is also a big OS.
For calculations you only could need micro OS (because apparently UEFI is more complete than BIOS). I think you need a micro OS at least to distribute process between cores and hyperthreads, and perhaps some memory management to prevent multiple access to some locations.
Regards, HSE.
Quote from: johnsa on April 17, 2022, 02:22:07 AM
for my personal OS project work. I had a small toy-OS running on a bunch of PCs
:thumbsup: That is the idea, something specific.
Quote from: johnsa on April 17, 2022, 02:22:07 AM
I can tell you a few things, you'd be surprised at how little difference running that bare metal actually makes over Windows 10. As a test I wrote a distance-marching software renderer, running from my bare long-mode UEFI OS vs. Windows showed about a 10% performance gain.
That is a question to answer. For sure depends on hardware.
Quote from: johnsa on April 17, 2022, 02:22:07 AM
To even get that took a lot of work making a set of drivers of AMD and NVidia gfx cards..
I went on to write an HD Audio driver so I had some sound playing too..
:biggrin: :biggrin: That is what can be eliminated for calculations!
Quote from: johnsa on April 17, 2022, 02:22:07 AM
I'll share the code for the bits of it if you like, just PM me.
:thumbsup: Thanks. Just learning now, but some questions will arise in the way.
Hi !
I'm writing: mov rax, pBootServices
invoke [rax].EFI_BOOT_SERVICES.LocateProtocol, ADDR EFI_MP_SERVICES_PROTOCOL_GUID, NULL, ADDR MpProtocol
and ObjConv say assemble is: mov rcx, qword ptr [pBootServices] ; 0A08 _ 48: 8B. 0D, 00000000(rel)
lea rcx, ptr [EFI_MP_SERVICES_PROTOCOL_GUID]; 0A0F _ 48: 8D. 0D, 00000000(rel)
xor edx, edx ; 0A16 _ 33. D2
lea r8, ptr [rsp+30H] ; 0A18 _ 4C: 8D. 44 24, 30
call qword ptr [rcx+140H] ; 0A1D _ FF. 91, 00000140
but must be: mov rax, pBootServices <---
lea rcx, ptr [EFI_MP_SERVICES_PROTOCOL_GUID]; 0A0F _ 48: 8D. 0D, 00000000(rel)
xor edx, edx ; 0A16 _ 33. D2
lea r8, ptr [rsp+30H] ; 0A18 _ 4C: 8D. 44 24, 30
call qword ptr [rax+140H] <---
I don't know if is a UASM problem or a bad method definition: STDFUNC LocateProtocol, <voidarg>, Protocol:PTR EFI_GUID, Registration:PTR, ppInterface:PTR
Thanks in advance, HSE
That doesn't look right, I'll check it out.
That was if MpProcotol is an structure, if MpProtocol is a qword then everything is correct (but anyway is a pointer :dazzled:)