Example
Example of assembler code called by a C subroutine.
The following is an example of assembler code called by a C routine:
# Call this assembly routine from C routine:
# callfile.c:
# main()
# {
# examlinkage();
# }
# Compile as follows:
# cc -o callfile callfile.c examlinkage.s
#
#################################################################
# On entry to a procedure(callee), all or some of the
# following steps should be done:
# 1. Save the link register at offset 8 from the
# stack pointer for non-leaf procedures.
# 2. If any of the CR bits 8-19(CR2,CR3,CR4) is used
# then save the CR at displacement 4 of the current
# stack pointer.
# 3. Save all non-volatile FPRs used by this routine.
# If more that three non-volatile FPR are saved,
# a call to ._savefn can be used to
# save them (n is the number of the first FPR to be
# saved).
# 4. Save all non-volatile GPRs used by this routine
# in the caller's GPR SAVE area (negative displacement
# from the current stack pointer r1).
# 5. Store back chain and decrement stack pointer by the
# size of the stack frame.
#
# On exit from a procedure (callee), all or some of the
# following steps should be done:
# 1. Restore all GPRs saved.
# 2. Restore stack pointer to value it had on entry.
# 3. Restore Link Register if this is a non-leaf
# procedure.
# 4. Restore bits 20-31 of the CR is it was saved.
# 5. Restore all FPRs saved. If any FPRs were saved then
# a call to ._savefn can be used to restore them
# (n is the first FPR to be restored).
# 6. Return to caller.
#################################################################
# The following routine calls printf() to print a string.
# The routine performs entry steps 1-5 and exit steps 1-6.
# The prolog/epilog code is for small stack frame size.
# DSA + 8 < 32k
#################################################################
.file "examlinkage.s"
#Static data entry in T(able)O(f)C(ontents)
.toc
T.examlinkage.c: .tc examlinkage.c[tc],examlinkage.c[rw]
.globl examlinkage[ds]
#examlinkage[ds] contains definitions needed for
#runtime linkage of function examlinkage
.csect examlinkage[ds]
.long .examlinkage[PR]
.long TOC[tc0]
.long 0
#Function entry in T(able)O(f)C(ontents)
.toc
T.examlinkage: .tc .examlinkage[tc],examlinkage[ds]
#Main routine
.globl .examlinkage[PR]
.csect .examlinkage[PR]
# Set current routine stack variables
# These values are specific to the current routine and
# can vary from routine to routine
.set argarea, 32
.set linkarea, 24
.set locstckarea, 0
.set nfprs, 18
.set ngprs, 19
.set szdsa,
8*nfprs+4*ngprs+linkarea+argarea+locstckarea
#PROLOG: Called Routines Responsibilities
# Get link reg.
mflr 0
# Get CR if current routine alters it.
mfcr 12
# Save FPRs 14-31.
bl ._savef14
cror 31, 31, 31
# Save GPRs 13-31.
stm 13, -8*nfprs-4*ngprs(1)
# Save LR if non-leaf routine.
st 0, 8(1)
# Save CR if current routine alters it.
st 12, 4(1)
# Decrement stack ptr and save back chain.
stu 1, -szdsa(1)
################################
#load static data address
#################################
l 14,T.examlinkage.c(2)
# Load string address which is an argument to printf.
cal 3, printing(14)
# Call to printf routine
bl .printf[PR]
cror 31, 31, 31
#EPILOG: Return Sequence
# Restore stack ptr
ai 1, 1, szdsa
# Restore GPRs 13-31.
lm 13, -8*nfprs-4*ngprs(1)
# Restore FPRs 14-31.
bl ._restf14
cror 31, 31, 31
# Get saved LR.
l 0, 8(1)
# Get saved CR if this routine saved it.
l 12, 4(1)
# Move return address to link register.
mtlr 0
# Restore CR2, CR3, & CR4 of the CR.
mtcrf 0x38,12
# Return to address held in Link Register.
brl
.tbtag 0x0,0xc,0x0,0x0,0x0,0x0,0x0,0x0
# External variables
.extern ._savef14
.extern ._restf14
.extern .printf[PR]
#################################
# Data
#################################
.csect examlinkage.c[rw]
.align 2
printing: .byte 'E,'x,'a,'m,'p,'l,'e,' ,'f,'o,'r,'
.byte 'P,'R,'I,'N,'T,'I,'N,'G
.byte 0xa,0x0