From: Robert Redelmeier on
In alt.lang.asm Terence <spamtrap(a)crayne.org> wrote in part:
> An interesting point in Frank Kotler's posting, is who gets to
> clean up the stack. Here Frank is doing it in the main program
> (obviously because the called rountines don't do this for him).
> But I was "brought up" on the Microsoft standard of the CALLED
> subprogram doing a RET N operation to clear the stack. All my
> hand- wriiten subroutine include this, beuase my main program is
> a Microsoft Fortran program which folows my description of the
> stack responsibility.

It is much easier to do caller-cleanup (whence the RET N
instruction) in FORTRAN with fixed param lists than in C
which allows a variable number of params e.g. printf()

-- Robert

From: robertwessel2 on
On Apr 20, 5:33�pm, Terence <spamt...(a)crayne.org> wrote:
> An interesting point in Frank Kotler's posting, is who gets to clean
> up the stack.
> Here Frank is doing it in the main program (obviously because the
> called rountines don't do this for him).
> But I was "brought up" on the Microsoft standard of the CALLED
> subprogram doing a RET N operation to clear the stack. All my hand-
> wriiten subroutine include this, beuase my main program is a Microsoft
> Fortran program which folows my description of the stack
> responsibility.
>
> So I assume Miscroft chnaged it's mind at some point in time, because
> obvious again, the referred called services aboove are Microsoft-
> written Windows service.


Win16 has always used what MS has called the Pascal calling
convention, and Win32 uses stdcall. Both of those are callee cleanup,
but stdcall passes parameters right-to-left (like cdecl), unlike
Pascal (which is left-to-right). C compilers use cdecl (which is
right-to-left and caller cleanup) by default. Left-to-right and
callee cleanup are both problems for C-style variable argument lists.
It is fairly conventional in Windows to make all API-style functions
(including most things exported from DLLs) use Pascal or stdcall as
appropriate for the system, although there is absolutely nothing
enforcing that, and in fact, the shared (DLL) versions of the CRT
supplied by MS use cdecl conventions for the C library functions.

Win64 uses a variation of the old fastcall convention for both intra-
program calls and API calls, which is also the case for most *nix
systems (IOW, the same calling convention is used intra- and inter-
program, but it�s not the same as the Win64 conventions). That does
simplify things.

And the convention moves around a bit for non-x86 platforms.

From: Terence on
A misunderstanding Frank!
I know the posting is about the use of Linux.
And an ASM program written as a main can call named sub-programs,
whether service or otherwise.

But this same main program can be used with Windows as long as what
its calls are valid for a Windows environment.

And here is the point.
When you write a 32-bit algorithm in ASM for an Intel chip, the main
code is valid whether for Windows or Linux, EXCEPT the calls to
services.

And I write for DOS and Windoss and change the subprogram library I
link with to match.
But I have also to match the calling convention or use a common one.
And FOrytran and C, as example, use different stack conventions.

In Linux the usage is to push parameters to the stack and call a
subprogram service, and on return, to clear the stack space used.
Microsoft's original preffered scheme was to have the called
subprogram clear the stackk on return.

From: Frank Kotler on
Terence wrote:
> An interesting point in Frank Kotler's posting, is who gets to clean
> up the stack.
> Here Frank is doing it in the main program (obviously because the
> called rountines don't do this for him).
> But I was "brought up" on the Microsoft standard of the CALLED
> subprogram doing a RET N operation to clear the stack. All my hand-
> wriiten subroutine include this, beuase my main program is a Microsoft
> Fortran program which folows my description of the stack
> responsibility.
>
> So I assume Miscroft chnaged it's mind at some point in time, because
> obvious again, the referred called services aboove are Microsoft-
> written Windows service.

[followups trimmed to asm groups... pearls before swine y'know]

Yeah... it's different in Windows. A "hello world in a window" is as
complicated as the X version, or worse. Something simpler will suffice.
I can't find a Windows example that's "right" - "push -11" is *not*
right, we're supposed to push -11 and call GetStandardHandle and use the
return from *that* as a handle. This worked anyway, in win98, IIRC.
It'll do...

; link /entry:start /subsystem:console hwin32.obj <wherever>\kernel32.lib

; you want this clutter in an include file, probably...

%define WriteFile _WriteFile(a)20
%define ExitProcess _ExitProcess@4


extern WriteFile
extern ExitProcess

global _start

section .text
; can put routines here, if you want
_start:

push dword 0 ; ??? unicode flag???
push dword num_chars ; return value
push dword MSGLEN
push dword msg
push dword -11 ; can this be right???
call WriteFile

; callee "cleans up stack" - removes all those
; parameters we pushed, via "ret N"


exit_ok:
push dword 0
exit:
call ExitProcess

section .bss
num_chars resd 1

section .rodata
msg db 'Hello, Console.', 13, 10
MSGLEN equ $ - msg
;----------------------------------

An approximate equivalent for Linux - this calls the kernel via the C
calling convention, instead of the int 80h interface - but winds up
executing exactly the same code, unless I'm mistaken...


; nasm -f elf hwcw.asm
; gcc hwcw.o -o hwcw
; ./hwcw

global main
extern write

section .data
msg db 'Hello, World!', 10
msg_len equ $ - msg
section .text
main:

push msg_len
push msg
push 1 ; stdout

call write
add esp, 12
; here we *do* have to "clean up stack"
; callee just ends in "ret"

ret

Note that besides the different stack handling, Windows takes a
parameter for the "return place" to return number of characters written,
while Linux returns it in eax... When it comes to GUI apps, the Xwindows
server is an app of its own - not part of the kernel at all. "I don't
think we're in Kansas anymore, Toto!" :)

Best,
Frank

From: Frank Kotler on
Terence wrote:
> A misunderstanding Frank!
> I know the posting is about the use of Linux.
> And an ASM program written as a main can call named sub-programs,
> whether service or otherwise.
>
> But this same main program can be used with Windows as long as what
> its calls are valid for a Windows environment.
>
> And here is the point.
> When you write a 32-bit algorithm in ASM for an Intel chip, the main
> code is valid whether for Windows or Linux, EXCEPT the calls to
> services.
>
> And I write for DOS and Windoss and change the subprogram library I
> link with to match.
> But I have also to match the calling convention or use a common one.
> And FOrytran and C, as example, use different stack conventions.

I'm not familiar with Fortran. How do they do it?

> In Linux the usage is to push parameters to the stack and call a
> subprogram service, and on return, to clear the stack space used.
> Microsoft's original preffered scheme was to have the called
> subprogram clear the stackk on return.

Right... AFAIK, they still do it that way, with a couple exceptions -
"wsprintf", I think... probably more...

Unless I'm mistaken, changing ".model flat stdcall" to ".model flat C"
would automatically adjust your code... with certain assemblers...

Best,
Frank