flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Main > Popad: Procedure epilogue question

Author
Thread Post new topic Reply to topic
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia

Popad: Procedure epilogue question

Hi, I'm looking for the best way to return error codes from my procs.
I use CDECL convention, my prologue and epilogue typically look like this:

Code:
mov eax,esp
pushad
mov ebp,eax
; pushad changes esp but since it's saved, I use ebp instead of esp
; exactly the same way to access procedure arguments:
; instead of e.g. mov ecx,[esp+4] I say "mov ecx,[ebp+4]"

...

; Reporting error and abort in case of something bad
popad
mov eax,EFI_NOT_FOUND ; for example
jmp .ExitProc

...

popad
mov eax,EFI_SUCCESS ; same as 0

.ExitProc:
ret


The question is: It all works but I don't very much like this template, namely, multiple popad's and I'm looking for a way to get rid of them Can I use something else? My idea is to directly modify 'EAX' in the stack before popping (not sure if all machines use the same order).
Something like this:

Code:
pushad
mov ebp,esp
sub ebp,SomeNumber ; Move ebp directly onto EAX 'shadow' in stack
mov [ebp],EFI_SUCCESS ; modifying 'EAX' in stack

; Accessing still available by adding some number to stack offset
; Originally: mov ecx,[esp+4], now: mov ecx,[ebp+SomeNumber]

...

; Reporting error and abort in case of something bad
mov [ebp],EFI_NOT_FOUND ; modifying 'EAX' in stack
jmp .ExitProc

...

.ExitProc:
popad
ret


Will it work?
Post 26 Oct 2016, 03:46
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15324
Location: Bigweld Industries

Re: Popad: Procedure epilogue question


MrFox wrote:
My idea is to directly modify 'EAX' in the stack before popping (not sure if all machines use the same order).
...
Will it work?

Yes. PUSHAD/POPAD works the same in all x86 compatible CPUs.
Post 26 Oct 2016, 04:15
View user's profile Send private message Visit poster's website Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia

Yay, thanks!
Pushad/popad work with 32bit registers.
What can I use in case of 64bit code? (I'm trying to think of portability)
Post 26 Oct 2016, 04:24
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15324
Location: Bigweld Industries

The is no 64-bit equivalent of PUSHA or POPA. You can use individual PUSH/POP or adjust RSP and directly save/restore registers to/from the stack with MOV.
Post 26 Oct 2016, 04:27
View user's profile Send private message Visit poster's website Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia

Oops, ok, thanks!!!
Post 26 Oct 2016, 04:37
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 503
Location: New Zealand


revolution wrote:
The is no 64-bit equivalent of PUSHA or POPA. You can use individual PUSH/POP or adjust RSP and directly save/restore registers to/from the stack with MOV.

[rant]Yet another example of the half-baked X86-64bit implementation, "thanks" to AMD for developing it and "thanks" to Intel for falling asleep and dropping the ball. Although it's completely incompatible with X86 maybe IA64 would've been better after all. Too late now though... the last Itanium processor was produced about 4 years ago?[/rant]

_________________
FAMOS - the first memory operating system
Post 26 Oct 2016, 10:48
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15324
Location: Bigweld Industries


neville wrote:
[rant]Yet another example of the half-baked X86-64bit implementation, "thanks" to AMD for developing it and "thanks" to Intel for falling asleep and dropping the ball. Although it's completely incompatible with X86 maybe IA64 would've been better after all. Too late now though... the last Itanium processor was produced about 4 years ago?[/rant]

ARM also did the same with their 32-to-64 transition; LDM and STM were removed. I guess these types of compound instructions make it difficult to implement multi-GHz high-performance CPUs - or something like that. It tends to make the code footprint a bit larger. I would hope that the payback from a simpler decoding stage made up for the loss with better instruction throughput.

But the code generated from C compilers also has a large influence upon which instructions are deemed important. Perhaps C doesn't make much use of PUSHA and POPA so they were excised in favour of improving other more used portions of the CPU.
Post 26 Oct 2016, 11:06
View user's profile Send private message Visit poster's website Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 232
Location: film "CandyMan" directed through Bernard Rose

I am using such a PUSHA/POPA substitute:

Code:
AnyCode:
        CALL    PushAll
        ;...
        CALL    PopAll
        RET

PushAll:
        XCHG    R15,[RSP]      
        PUSH    R14
        PUSH    R13
        PUSH    R12
        PUSH    R11
        PUSH    R10
        PUSH    R9
        PUSH    R8
        PUSH    RBP
        PUSH    RSI
        PUSH    RDI
        PUSH    RDX
        PUSH    RCX
        PUSH    RBX
        PUSH    RAX
        PUSH    R15
        MOV     R15,[RSP+15*8]
        RET

PopAll:
        POP     R15             
        POP     RAX
        POP     RBX
        POP     RCX
        POP     RDX
        POP     RDI
        POP     RSI
        POP     RBP
        POP     R8
        POP     R9
        POP     R10
        POP     R11
        POP     R12
        POP     R13
        POP     R14
        XCHG    [RSP],R15
        RET


_________________
smaller is better
Post 26 Oct 2016, 11:40
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1386
Location: Toronto, Canada

Order is same.
I use it always:

Code:

virtual at 0
regsAtPopa:
    .reg_EDI dd ?
    .reg_ESI dd ?
    .reg_EBP dd ?
    .Skip    dd ?
    .reg_EBX dd ?
    .reg_EDX dd ?
    .reg_ECX dd ?
    .reg_EAX dd ?
end virtual

...

mov [esp + regsAtPopa.reg_EAX], ... return value ...
popa
ret



You can also return other registers while preserving the rest.
Post 26 Oct 2016, 14:54
View user's profile Send private message Send e-mail Reply with quote
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia

Thanks, guys!
I'm now using "mov [esp+28], eax" and it works just fine!
Post 29 Oct 2016, 13:29
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2017, Tomasz Grysztar.