## Assembly - push/pop registers

In this forum members can discuss topics about specific programming languages.
Oliver1978
Posts: 165
Joined: Sat Nov 22, 2014 9:13 pm
Location: Erfurt, Germany

### Assembly - push/pop registers

I'm aware that under Windows one should push the registers ebx/edi/esi prior to facilitating, and pop them back later (that's what I've learned). I guess that also goes for their 64 bit equivalents. But what about the registers r8 through r15? And how about under Linux? Will I have to push/pop those regs accordingly?
49.157.5694.1125

rayfil
Posts: 1401
Joined: Sun Mar 26, 2006 4:30 am
Contact:

### Re: Assembly - push/pop registers

I'm aware that under Windows one should push the registers ebx/edi/esi prior to facilitating ....
This used to be true up to Win98. Windows seemed to drop that requirement starting at least with WinXP. I can remember one program I wrote where I popped the esi/edi registers in the wrong order and the app worked perfectly on WinXP but crashed on Win98!

Windows seems to have learned not to rely on other programmers to save any general purpose registers for their own internal use. However, I cannot vouch that Linux has learned the same thing, knowing nothing about that OS.
When you assume something, you risk being wrong half the time.

Oliver1978
Posts: 165
Joined: Sat Nov 22, 2014 9:13 pm
Location: Erfurt, Germany

### Re: Assembly - push/pop registers

Thanks, ray

Is actually anybody into 64 bit assembly programming under Linux?
49.157.5694.1125

stephj
Posts: 5
Joined: Sun Apr 13, 2014 5:22 pm
Location: Lancashire, UK

### Re: Assembly - push/pop registers

I have written a few x64 subroutines called from Windows C/C++ programs to number crunch multiple precision arrays of numbers together.

The subroutines I have written are are all 'leaf' functions, in which you may not modify the stack pointer, or certain registers. Therefore push, pop, and call instructions are all forbidden. To save registers, you must save them within your routine and restore them afterwards.

If you wish to call other routines from yours you have to write prologue and epilogue sections in the routine so that the operating system knows how to tidy things up if your routine crashes. That's the reason why I stick to leaf code. It is much simpler.

x64 Linux and x64 Windows work in a similar fashion but use different registers to pass parameters etc.

Some guidance can be found at:-

http://en.wikipedia.org/wiki/X86_callin ... onventions

And the full Linux specification is at:-

http://www.x86-64.org/documentation/abi.pdf

The following is a two page summary of the above

http://courses.cs.washington.edu/course ... _recap.pdf

An example of a Windows leaf subroutine to add two __int64 arrays together follows. This is only for Windows, as it uses the Windows calling convention - parameters in RCX,RDX,r8 and r9, but a Linux equivalent would not be much different.

Code: Select all

;	void add64(__int64 *arr1, __int64 *arr2, __int64 start, __int64 end);
;       x64 Macro Assembler multiple precision function to add two arrays of __int64 elements.
;	At the start of this call, RCX=arr1, RDX=arr2, r8=start, r9=end

MOV	R10,RCX		; *arr1
MOV	R11,RDX		; *arr2
MOV	RCX,R9
SUB	RCX,R8
INC	RCX
CLC
MOV	RAX,[R10+R9*8]
MOV	[R11+R9*8],RAX	; Save value in arr2
DEC	R9		; Next element
RET