OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:41 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Simple Assembly UEFI Application -- Can't Exit Boot Serv
PostPosted: Mon Apr 29, 2019 2:22 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
zaval wrote:
[code]
main:
push rbx
push r12
sub rsp, 6 * 8 ; keeping it 16 byte aligned
The stack isn't aligned at the EFI entry point (it was before the call instruction executed). It is misaligned by 8 upon entry since the return address was pushed on the stack by the call. 8+8+6*8 has to have an additional 8 added to it to get the stack properly aligned. It should be sub rsp, 6 * 8 + 8


Top
 Profile  
 
 Post subject: Re: Simple Assembly UEFI Application -- Can't Exit Boot Serv
PostPosted: Mon Apr 29, 2019 3:28 pm 
Online
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 641
Location: Ukraine, Bachmut
MichaelPetch wrote:
zaval wrote:
Code:
main:
   push   rbx
   push   r12
   sub   rsp, 6 * 8   ; keeping it 16 byte aligned


The stack isn't aligned at the EFI entry point (it was before the call instruction executed). It is misaligned by 8 upon entry since the return address was pushed on the stack by the call. 8+8+6*8 has to have an additional 8 added to it to get the stack properly aligned. It should be sub rsp, 6 * 8 + 8

yes, I added and removed some nonvolatile registers and it ended up misaligned (this is the price of writing in assembly). it is allowed to be misaligned within a prolog (the piece above), but the prolog should make it aligned back. it's my fault, I'll fix it. because the main function doesn't make use of any stack variables, it's enough to make it 5 * 8.

Btw, your code preserves volatile registers (why?) and doesn't nonvolatile ones (rbx for example), but uses it. For example, here:
Code:
printhex:
                         ; Stack msialigned by 8 at function entry
mov rbp, 16          ; <--- should be preserved before usage
push rax             ; <--- shouldn't be preserved
push rcx              ; <--- shouldn't be preserved
push rdx                ; 3 pushes also align stack on 16 byte boundary
                         ; (8+3*8)=32, 32 evenly divisible by 16
sub rsp, 32             ; Allocate 32 bytes of shadow space
.loop:
    rol rbx, 4         ;<--- should be preserved before usage

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: Simple Assembly UEFI Application -- Can't Exit Boot Serv
PostPosted: Mon Apr 29, 2019 4:09 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
zaval wrote:
MichaelPetch wrote:
zaval wrote:
Code:
main:
   push   rbx
   push   r12
   sub   rsp, 6 * 8   ; keeping it 16 byte aligned


The stack isn't aligned at the EFI entry point (it was before the call instruction executed). It is misaligned by 8 upon entry since the return address was pushed on the stack by the call. 8+8+6*8 has to have an additional 8 added to it to get the stack properly aligned. It should be sub rsp, 6 * 8 + 8

yes, I added and removed some nonvolatile registers and it ended up misaligned (this is the price of writing in assembly). it is allowed to be misaligned within a prolog (the piece above), but the prolog should make it aligned back. it's my fault, I'll fix it. because the main function doesn't make use of any stack variables, it's enough to make it 5 * 8.

Btw, your code preserves volatile registers (why?) and doesn't nonvolatile ones (rbx for example), but uses it. For example, here:
Code:
printhex:
                         ; Stack msialigned by 8 at function entry
mov rbp, 16          ; <--- should be preserved before usage
push rax             ; <--- shouldn't be preserved
push rcx              ; <--- shouldn't be preserved
push rdx                ; 3 pushes also align stack on 16 byte boundary
                         ; (8+3*8)=32, 32 evenly divisible by 16
sub rsp, 32             ; Allocate 32 bytes of shadow space
.loop:
    rol rbx, 4         ;<--- should be preserved before usage
Because his printhex routine did it, and since printhex can be any calling convention he chooses I kept it as is so that I didn't have to look over the rest of his code to find and change other register usage if I shifted to using nonvolatile registers (I had actually considered doing that originally, and chose to keep his code more or less the same where I could). The only intention I had with printhex was to assure that the alignment was maintained across the function calls, and to keep his calling convention for it the same. As an internal function printhex doesn't need to be a specific convention. There are other things in that code that are inefficient but my goal was to keep his code the same where I could.

Would have been a different story is printhex and others had some kind of external linkage and there was a requirement for the 64-bit ABI. It would have been a far bigger concern had the main code (starting at the entry point) had to return back to the caller(FI shell etc), but it doesn't so one can get away in this case with non standard register usage and conventions as long as he calls the UEFI services with the required registers, stack layout, and alignment. This of course isn't good coding practice especially if he were to return back to an EFI shell.

Had I written this it would have been substantially different. I had also observed that although this code generates an EFI program that seems to work, and Objdump understands it enough to dump it as a 64-bit PE file, but interestingly enough the utility file sees it only as some kind of DOS executable. I didn't spend time looking at file's source code and debugging it to find out what it didn't like or whether there may be a real compatibility issue or not.


Top
 Profile  
 
 Post subject: Re: Simple Assembly UEFI Application -- Can't Exit Boot Serv
PostPosted: Mon May 13, 2019 6:42 pm 
Offline

Joined: Fri Apr 26, 2019 3:46 pm
Posts: 6
Michael, Zaval, everybody, thank you very much -- my complete ignorance of the stack requirements for fastcall was indeed the source of the problem. All I really wanted is to get UEFI out of the way in as short a code sequence as I can manage... and now I have it!

Ignorance is bliss only when what you're ignorant of doesn't bite you in the ... anyway, much appreciated.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 19 posts ]  Go to page Previous  1, 2

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 57 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group