diff doc/manual/callconvs/callconv_x86.tex @ 472:e5820b7a3fbc

doc: - some more plan 9 disas examples - x86 callconv doc updated: * mainly info about aggregate passing and returning * removing section about pascal calling convention, as dyncall doesn't support 16bit abis - some cleanups
author Tassilo Philipp
date Thu, 10 Feb 2022 17:32:05 +0100
parents b47168dacba6
children 17287342e273
line wrap: on
line diff
--- a/doc/manual/callconvs/callconv_x86.tex	Mon Feb 07 23:29:24 2022 +0100
+++ b/doc/manual/callconvs/callconv_x86.tex	Thu Feb 10 17:32:05 2022 +0100
@@ -95,15 +95,17 @@
 \begin{itemize}
 \item stack parameter order: right-to-left
 \item caller cleans up the stack
-\item all arguments are pushed onto the stack
+\item all arguments are pushed onto the stack (as dwords)
+\item arguments \textgreater\ 64 bits are pushed as a sequence of dwords
+\item aggregates (structs, unions) are pushed as a sequence of dwords
 \end{itemize}
 
 \paragraph{Return values}
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers
-\item return values \textgreater\ 64 bits (e.g. structures) are returned by the caller allocating the space and
+\item integers and aggregates (structs, unions) \textgreater\ 32 and \textless=\ 64 bits are returned via the eax and edx registers
+\item return values \textgreater\ 64 bits (e.g. aggregates) are returned by the caller allocating the space and
 passing a pointer to the callee as a new, implicit first parameter (this means, on the stack)
 \item floating point types are returned via the st0 register (except on Minix, where they are returned as integers are)
 \end{itemize}
@@ -172,15 +174,20 @@
 \item called function cleans up the stack
 \item first two integers/pointers (\textless=\ 32bit) are passed via ecx and edx (even if preceded by other arguments)
 \item if first argument is a 64 bit integer, it is passed via ecx and edx
-\item all other parameters are pushed onto the stack
+\item all other parameters are pushed onto the stack (as dwords)
+\item arguments \textgreater\ 64 bits are pushed as a sequence of dwords
+\item aggregates (structs, unions) are pushed as a sequence of dwords, but are never split between registers and stack (if registers are still available and
+aggregate doesn't fit entirely into ecx and edx, it is passed via the stack and remaining registers are free for subsequent arguments)
 \end{itemize}
 
 \paragraph{Return values}
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers@@@verify
-\item floating point types are returned via the st0 register@@@ really ?
+\item integers and aggregates (structs, unions) \textgreater\ 32 and \textless=\ 64 bits are returned via the eax and edx registers
+\item return values \textgreater\ 64 bits (e.g. aggregates) are returned by the caller allocating the space and
+passing a pointer to the callee as a new, implicit first parameter (always via the stack, never via a register)
+\item floating point types are returned via the st0 register
 \end{itemize}
 
 
@@ -244,17 +251,21 @@
 \item stack parameter order: right-to-left
 \item called function cleans up the stack
 \item first two integers/pointers (\textless=\ 32bit) are passed via ecx and edx (even if preceded by other arguments)
-\item if first argument is a 64 bit integer, it is pushed on the stack and the two registers are skipped 
-\item all other parameters are pushed onto the stack
+\item arguments \textgreater\ 32 bits are pushed onto the stack as a sequence of dwords (never passed via registers, any respective register is skipped and not used for subsequent args)
+\item all other parameters are pushed onto the stack (as dwords)
+\item aggregates (structs, unions) are pushed as a sequence of dwords, and never passed via registers (no matter their size, any respective register is skipped and not used for subsequent args)
+\item varargs are always passed via the stack
 \end{itemize}
 
 
 \paragraph{Return values}
 
 \begin{itemize}
-\item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register.
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers.
-\item floating point types are returned via the st0.
+\item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
+\item integers \textgreater\ 32 and \textless=\ 64 bits are returned via the eax and edx registers
+\item aggregates (structs, unions) of any size are returned by the caller allocating the space and
+passing a pointer to the callee as a new, implicit first parameter (always via ecx), that same pointer is returned in eax
+\item floating point types are returned via the st0
 \end{itemize}
 
 
@@ -320,8 +331,12 @@
 \begin{itemize}
 \item stack parameter order: left-to-right
 \item called function cleans up the stack
-\item first three integers/pointers (with exception of method pointers) (\textless=\ 32bit) are passed via eax, ecx and edx (even if preceded or interleaved by other arguments)
+\item first three integers/pointers (with exception of method pointers) (\textless=\ 32bit) are passed via eax, ecx and edx (preceding or interleaved arguments that are not passed via registers are pushed onto the stack)
+\item arguments \textgreater\ 32 bits are passed as a pointer to the value
+\item aggregates (structs, unions) are pushed as a sequence of dwords, and never passed via registers (no matter their size)
+\item varargs are always passed via the stack
 \item all other parameters are pushed onto the stack
+\item the direction flag is clear on entry and must be returned clear % mention it first, above @@@
 \end{itemize}
 
 
@@ -331,10 +346,10 @@
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers
+\item integers and aggregates (structs, unions) \textgreater\ 32 and \textless=\ 64 bits are returned via the eax and edx registers
 \item floating point types are returned via the st0 register
-\item all others (e.g. all structs, return values \textgreater\ 64 bits, ...) are returned by the caller allocating the space and
-passing a pointer to the callee as a new, implicit first parameter
+\item return values \textgreater\ 32 bits (e.g. aggregates, long long, ...) are returned by the caller allocating the space and
+passing a pointer to the callee as a new, implicit {\bf last} parameter
 \end{itemize}
 
 
@@ -398,9 +413,9 @@
 \item stack parameter order: right-to-left
 \item called function cleans up the stack
 \item first four integers/pointers (\textless=\ 32bit) are passed via eax, edx, ebx and ecx (even if preceded by other arguments)
-\item arguments \textgreater 32 bits, as well as all subsequent arguments, are passed via the stack
+\item arguments \textgreater\ 32 bits, as well as all subsequent arguments, are passed via the stack
+\item aggregates (structs, unions) are passed as a pointer to the aggregate
 \item all other parameters are pushed onto the stack
-\item varargs are always passed via the stack
 \end{itemize}
 
 
@@ -408,8 +423,10 @@
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers@@@ verify
-\item floating point types are returned via the st0 register@@@ really ?
+\item integers \textgreater\ 32 bits and \textless=\ 64 bits are returned via the eax and edx registers
+\item aggregates (structs, unions) \textless=\ 32 bits are returned in eax
+\item aggregates (structs, unions) \textgreater\ 32 bits are returned by the caller allocating the space and
+passing a pointer to the callee via esi, that same pointer is returned in eax
 \end{itemize}
 
 
@@ -469,10 +486,12 @@
 \paragraph{Parameter passing}
 
 \begin{itemize}
-\item Stack parameter order: right-to-left
-\item Called function cleans up the stack
-\item All parameters are pushed onto the stack
-\item Stack is usually 4 byte aligned (GCC \textgreater=\ 3.x seems to use a 16byte alignement)
+\item stack parameter order: right-to-left
+\item called function cleans up the stack
+\item all parameters are pushed onto the stack (as dwords)
+\item arguments \textgreater\ 64 bits are pushed as a sequence of dwords
+\item aggregates (structs, unions) are pushed as a sequence of dwords
+\item stack is usually 4 byte aligned (GCC \textgreater=\ 3.x seems to use a 16byte alignement)
 \item the direction flag is clear on entry and must be returned clear % mention it first, above @@@
 \end{itemize}
 
@@ -482,7 +501,9 @@
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers
+\item integers and aggregates (structs, unions) \textgreater\ 32 and \textless=\ 64 bits are returned via the eax and edx registers
+\item return values \textgreater\ 64 bits (e.g. aggregates) are returned by the caller allocating the space and
+passing a pointer to the callee as a new, implicit first parameter (this means, on the stack)
 \item floating point types are returned via the st0 register
 \end{itemize}
 
@@ -545,9 +566,11 @@
 
 \begin{itemize}
 \item stack parameter order: right-to-left
-\item called function cleans up the stack
+\item called function cleans up the stack (except for variadic functions where the caller cleans up)
 \item first parameter (this pointer) is passed via ecx
 \item all other parameters are pushed onto the stack
+\item arguments \textgreater\ 64 bits are pushed as a sequence of dwords
+\item aggregates (structs, unions) are pushed as a sequence of dwords
 \end{itemize}
 
 % introduce mangling section? \item Function name is decorated by prepending a '@' character and appending a '@' character and the number of bytes (decimal) of stack space required
@@ -556,8 +579,10 @@
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers@@@verify
-\item floating point types are returned via the st0 register@@@ really ?
+\item integers \textgreater\ 32 bits and \textless=\ 64 bits are returned via the eax and edx
+\item aggregates (structs, unions) of any size are returned by the caller allocating the space and passing
+a pointer to the callee as a new, implicit first parameter, that same pointer is returned in eax
+\item floating point types are returned via the st0 register
 \end{itemize}
 
 
@@ -668,73 +693,10 @@
 \subsubsection{pascal}
 
 The best known uses of the pascal calling convention are the 16 bit OS/2 APIs, Microsoft Windows 3.x and Borland Delphi 1.x.
-
-\paragraph{Registers and register usage}
-
-\begin{table}[h]
-\begin{tabular*}{0.95\textwidth}{3 B}
-Name          & Brief description\\
-\hline
-{\bf eax}     & scratch, return value\\
-{\bf ebx}     & preserve\\
-{\bf ecx}     & scratch\\
-{\bf edx}     & scratch, return value\\
-{\bf esi}     & preserve\\
-{\bf edi}     & preserve\\
-{\bf ebp}     & preserve\\
-{\bf esp}     & stack pointer\\
-{\bf st0}     & scratch, floating point return value\\
-{\bf st1-st7} & scratch\\
-\end{tabular*}
-\caption{Register usage on x86 pascal calling convention}
-\end{table}
-
-\paragraph{Parameter passing}
-
-\begin{itemize}
-\item stack parameter order: left-to-right
-\item called function cleans up the stack
-\item all parameters are pushed onto the stack
-\end{itemize}
-
-
-\paragraph{Return values}
+It is a variation of stdcall, however, arguments are passed from left-to-right.
+Since this calling convention is for 16-bit APIs, it is not discussed in
+further detail, here.
 
-\begin{itemize}
-\item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits are returned via the eax and edx registers
-\item floating point types are returned via the st0 register
-\end{itemize}
-
-
-\paragraph{Stack layout}
-
-Stack directly after function prolog:\\
-
-\begin{figure}[h]
-\begin{tabular}{5|3|1 1}
-                                  & \vdots         &                                &                              \\
-\hhline{~=~~}
-register save area                & \hspace{4cm}   &                                & \mrrbrace{6}{caller's frame} \\
-\hhline{~-~~}
-local data                        &                &                                &                              \\
-\hhline{~-~~}
-\mrlbrace{3}{parameter area}      & arg 0          & \mrrbrace{3}{stack parameters} &                              \\
-                                  & \ldots         &                                &                              \\
-                                  & arg n-1        &                                &                              \\
-\hhline{~-~~}
-                                  & return address &                                &                              \\
-\hhline{~=~~}
-register save area                &                &                                & \mrrbrace{4}{current frame}  \\
-\hhline{~-~~}
-local data                        &                &                                &                              \\
-\hhline{~-~~}
-parameter area                    &                &                                &                              \\
-\hhline{~-~~}
-                                  & \vdots         &                                &                              \\
-\end{tabular}
-\caption{Stack layout on x86 pascal calling convention}
-\end{figure}
 
 
 \clearpage
@@ -767,6 +729,9 @@
 \item stack parameter order: right-to-left
 \item caller cleans up the stack
 \item all parameters are pushed onto the stack
+\item all parameters are pushed onto the stack (as dwords)
+\item arguments \textgreater\ 64 bits are pushed as a sequence of dwords
+\item aggregates (structs, unions) are pushed as a sequence of dwords
 \end{itemize}
 
 \pagebreak
@@ -775,8 +740,8 @@
 
 \begin{itemize}
 \item return values of pointer or integral type (\textless=\ 32 bits) are returned via the eax register
-\item integers \textgreater\ 32 bits or structures are returned by the caller allocating the space and
-passing a pointer to the callee as a new, implicit first parameter (this means, on the stack)
+\item integers \textgreater\ 32 bits and aggregates (structs, unions) of any size are returned by the caller allocating
+the space and passing a pointer to the callee as a new, implicit first parameter, that same pointer is returned in eax
 \item floating point types are returned via the st0 register (called F0 in plan9 8a's terms)
 \end{itemize}