Author Topic: Unified Extensible Firmware Interface (UEFI) Example  (Read 2135 times)

AW

  • Member
  • *****
  • Posts: 2442
  • Let's Make ASM Great Again!
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #15 on: October 20, 2019, 09:31:49 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

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #16 on: October 20, 2019, 09:38:49 AM »
here :undecided:
Code: [Select]
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
Code: [Select]
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;
}
May the source be with you

AW

  • Member
  • *****
  • Posts: 2442
  • Let's Make ASM Great Again!
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #17 on: October 20, 2019, 09:45:32 AM »
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.

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #18 on: October 20, 2019, 09:57:51 AM »
 :sad:
« Last Edit: October 27, 2019, 05:07:40 AM by TimoVJL »
May the source be with you

AW

  • Member
  • *****
  • Posts: 2442
  • Let's Make ASM Great Again!
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #19 on: October 20, 2019, 07:08:47 PM »
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[];

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #20 on: October 20, 2019, 09:35:45 PM »
or a volatile pointers to avoid unnecessary copying ?
Code: [Select]
/* 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

and cmdline.c needs a fix too
Code: [Select]
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";
}
May the source be with you

KradMoonRa

  • Regular Member
  • *
  • Posts: 46
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #21 on: October 21, 2019, 12:59:21 AM »
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
Code: [Select]
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
Code: [Select]
/* 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_?()

johnsa

  • Member
  • ****
  • Posts: 791
    • Uasm
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #22 on: October 21, 2019, 01:40:55 AM »
I like the improved consistency of those calls, let me make the same on the 2.50 branch.

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #23 on: October 21, 2019, 01:50:57 AM »
Code: [Select]
.x64p
OPTION WIN64:15
OPTION STACKBASE:RSP
OPTION LITERALS:ON
;OPTION ARCH:AVX
OPTION CASEMAP:NONE

include efi.inc
include efiUtil.inc

END
Code: [Select]
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.
Code: [Select]
.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
« Last Edit: October 21, 2019, 03:43:52 AM by TimoVJL »
May the source be with you

johnsa

  • Member
  • ****
  • Posts: 791
    • Uasm
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #24 on: October 21, 2019, 02:17:29 AM »
the MSVC version of 2.50 branch with the changes for avx/sse const strings isn't giving me any errors.

nidud

  • Member
  • *****
  • Posts: 1800
    • https://github.com/nidud/asmc
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #25 on: October 21, 2019, 02:18:43 AM »
Some thoughts about the implementation of this.

The strings used are tokens so they could be integer values:

/* global variables */

/* global strings for arch:sse/avx instructions to use */
//extern char *MOVE_SIMD_DWORD;
//extern char *MOVE_SIMD_QWORD;
...
#define MOVE_SIMD_DWORD (T_MOVD + (ModuleInfo.arch * (T_VMOVD - T_MOVD)))
#define MOVE_SIMD_QWORD (T_MOVQ + (ModuleInfo.arch * (T_VMOVQ - T_MOVQ)))


Assuming the distance is equal ModuleInfo.arch could be a fixed integer or byte value.

In 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";

ModulePassInit():
ModuleInfo.arch = Options.arch;


The cmdline.c will set the option so uasm a.asm -avx b.asm will apply to module b.

static void OPTQUAL Set_SSE(void)
{
   Options.arch = FALSE;
   //ModuleInfo.arch = ARCH_SSE;
   //MODULEARCH = 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");
}

static void OPTQUAL Set_AVX(void)
{
   Options.arch = TRUE;
   //ModuleInfo.arch = ARCH_AVX;
   //MODULEARCH = 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");
}


option.c changes the current module:

/* OPTION ARCH:SSE/AVX */
OPTFUNC( SetArch )
{
   int i = *pi;
   //struct asym *archSym = SymFind("@Arch");

   if (tokenarray.token == T_ID) {
      if (0 == _stricmp(tokenarray.string_ptr, "SSE")) {
         //MODULEARCH = ARCH_SSE;
         ModuleInfo.arch = FALSE;
         //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");
         //archSym->value = ARCH_SSE;
      }
      else if (0 == _stricmp(tokenarray.string_ptr, "AVX")) {
         //MODULEARCH = ARCH_AVX;
         ModuleInfo.arch = TRUE;
         //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");
         //archSym->value = ARCH_AVX;
      }


invoke.c and other files using MOVE_ needs format %r:

   AddLineQueueX(" %r %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);
   //if (param->sym.mem_type == MT_REAL4)
   //   AddLineQueueX(" %s %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);
   //else
   //   AddLineQueueX(" %s %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);


AW

  • Member
  • *****
  • Posts: 2442
  • Let's Make ASM Great Again!
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #26 on: October 21, 2019, 02:50:22 AM »
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.

johnsa

  • Member
  • ****
  • Posts: 791
    • Uasm
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #27 on: October 21, 2019, 05:57:09 AM »
I've put a binary I've built now on the site, please try that:
www.terraspace.co.uk/uasm250_x64.zip
www.terraspace.co.uk/uasm250_x86.zip

TimoVJL

  • Member
  • ***
  • Posts: 476
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #28 on: October 21, 2019, 06:50:34 AM »
Yes, it works.

Also Clang compiled version using volatile works.
http://masm32.com/board/index.php?topic=7942.msg89132#msg89132

May the source be with you

jj2007

  • Member
  • *****
  • Posts: 9804
  • Assembler is fun ;-)
    • MasmBasic
Re: Unified Extensible Firmware Interface (UEFI) Example
« Reply #29 on: October 21, 2019, 07:04:38 AM »
Error A2143: Symbol redefinition: memalign (and I never use this symbol)
Code: [Select]
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