flat assembler
Message board for the users of flat assembler.

Index > Main > Popad: Procedure epilogue question

Author
Thread Post new topic Reply to topic
MrFox



Joined: 17 Aug 2016
Posts: 52
Location: Russia
MrFox 26 Oct 2016, 03:46
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: 20451
Location: In your JS exploiting you and your system
revolution 26 Oct 2016, 04:15
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
MrFox 26 Oct 2016, 04:24
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: 20451
Location: In your JS exploiting you and your system
revolution 26 Oct 2016, 04:27
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
MrFox 26 Oct 2016, 04:37
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: 507
Location: New Zealand
neville 26 Oct 2016, 10:48
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: 20451
Location: In your JS exploiting you and your system
revolution 26 Oct 2016, 11:06
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: 414
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan 26 Oct 2016, 11:40
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: 1671
Location: Toronto, Canada
AsmGuru62 26 Oct 2016, 14:54
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
MrFox 29 Oct 2016, 13:29
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


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.