Assembly - push/pop registers

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

Assembly - push/pop registers

Post by Oliver1978 » Fri Jan 02, 2015 11:58 am

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

User avatar
rayfil
Administrator
Posts: 1400
Joined: Sun Mar 26, 2006 4:30 am
Location: Ontario, Canada
Contact:

Re: Assembly - push/pop registers

Post by rayfil » Fri Jan 02, 2015 6:42 pm

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.

User avatar
Oliver1978
Posts: 163
Joined: Sat Nov 22, 2014 9:13 pm
Location: Erfurt, Germany

Re: Assembly - push/pop registers

Post by Oliver1978 » Fri Jan 02, 2015 10:24 pm

Thanks, ray :)

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

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

Re: Assembly - push/pop registers

Post by stephj » Thu Jan 08, 2015 3:07 pm

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

PUBLIC		add64

add64		PROC

		MOV	R10,RCX		; *arr1
		MOV	R11,RDX		; *arr2
		MOV	RCX,R9
		SUB	RCX,R8
		INC	RCX
		CLC
ADDLOOP:
		MOV	RAX,[R10+R9*8]
		ADC	RAX,[R11+R9*8]
		MOV	[R11+R9*8],RAX	; Save value in arr2
		DEC	R9		; Next element
		LOOP	ADDLOOP
		RET
            
add64		ENDP
Last edited by stephj on Fri Jan 16, 2015 5:47 pm, edited 3 times in total.
Image

User avatar
Oliver1978
Posts: 163
Joined: Sat Nov 22, 2014 9:13 pm
Location: Erfurt, Germany

Re: Assembly - push/pop registers

Post by Oliver1978 » Fri Jan 09, 2015 11:35 am

Thank you stephj. I'll go through those documents asap.
49.157.5694.1125

Post Reply