User guide
10.2. THE SIAL-386 TRANSLATOR 183
When implementing sial-386 it was necessary to decide how t he Intel regis te r s
were to be used and what the BCPL calling sequence should be. The chosen r e gi ste r
allocation was as follows:
Intel register
Use
%eax A work register
%ebx
The A r egi s te r
%ecx
The B r egi s te r
%edx
The C r egi s te r
%esi
The G pointer
%edi
A work register
%ebp
The P pointer
The chosen BCPL calling sequence is as follows:
# Entry address must be in %eax
# The first argument must be in %ebx
leal <stack increment>(%ebp),%edx # Set %edx to the new P pointer
call *%eax # Subroutine jump to the entry point
The entry sequence is as follows:
# The first argument is in %ebx(=A)
# The new P pointer is in %edx(=C)
movl %ebp,0(%edx) # C!0 := P
movl %edx,%ebp # P := C
popl %edx # Get the return address
movl %edx,4(%ebp) # P!1 := return address
movl %eax,8(%ebp) # P!2 := entry address
movl %ebx,12(%ebp) # P!3 := the first argument
The return sequence is as follows:
# The result is in %ebx(=A)
movl 4(%ebp),%eax # Get the return address
movl 0(%ebp),%ebp # P := the saved P pointer
jmp *%eax # Jump to the return address
The structur e of sial-386 is simple. It mainly consists of a large switch within the
function scan that has a case for each function code and directive. For example, the
case for the function code kpg is as follows:
CASE f_kpg: cvfpg("KPG") // Call Gg(a,...) incrementing P by n
writef("*n movl %n(%%esi),%%eax", 4*gval)
writef("*n leal %n(%%ebp),%%edx", 4*pval)
writef("*n call **%%eax")
ENDCASE