Article View: alt.msdos.programmer
Article #188Re: Calling C functions from assembly
From: Dion Hollenbeck
Date: Wed, 02 Aug 1989 14:11
Date: Wed, 02 Aug 1989 14:11
84 lines
3147 bytes
3147 bytes
From article <12324@s.ms.uky.edu>, by simon@ms.uky.edu (G. Simon Gales):
> I'm trying to call some C functions from assembly, using MSC 5.0 and either
> MASM or TASM. I could write a dummy _main() in C, if this makes things
> easier, but I'm still not sure what needs to be setup to call a C subroutine.
>
> Can anyone clue me in on how to do this?
There is a section in the ref. manual dealing specifically with this,
but I will summarize. Be aware that I am summarizing from memory
and do not have the manual in front of me. I will address both calling
C functions from assembly and assembly being called by C.
Calling C from Assembly.
=======================
Pseudocode the calling interface so you know the order of the arguements.
Push the arguements onto the stack from right to left and push
multi-word args (floats, far ptrs....) from high to low. Be sure of
your memory model so that you can have the segment registers OK. Some
memory models ASSUME ES = DS so you must make it so before calling C
functions. For instance the tiny memory model assumes that
CS = DS = ES = SS. Results are returned in registers. A char in AL, a
short int in AX, a long int or float in AX/BX (low order in BX),
and a double in AX, BX, CX, DX high order in AX to low order in DX.
Calling Assembly from C.
========================
Here is a code fragment for ASM being called by C.
;; FUNCTION
;; read_ee_raw (ee_offset, numbytes, destination)
;;
;; int ee_offset ARG1
;; int num_bytes ARG2
;; char far *destination ARG3 - offset
;; ARG4 - segment
PUBLIC READ_EE_RAW
READ_EE_RAW PROC NEAR
PUSH BP ;set up frame pointer
MOV BP,SP
PUSH AX ;save registers used
PUSH DI
PUSH SI
PUSH DS
PUSH ES
LDS SI,[EEPROM_BASE] ;get seg:off ptr to EEPROM base
MOV AX,[BP+ARG1] ;get byte offset into EEPROM
SHL AX,1 ;make word offset
ADD SI,AX ;add to base offset
MOV DI,[BP+ARG3] ;get offset to destination
MOV AX,[BP+ARG4] ;get segment of destination
MOV ES,AX ;get in dest segreg
MOV CX,[BP+ARG2] ;get count of bytes to read
EEPROM_READ_LOOP:
LODSW ;read word - high byte is junk
STOSB ;write byte
LOOP EEPROM_READ_LOOP ;continue until done
POP ES ;restore registers used
POP DS
POP SI
POP DI
POP AX
POP BP ;restore frame pointer
RET
READ_EE_RAW ENDP
No other explanation should be necessary except to say to read the
manual to be sure what registers should be saved and restored. You
cannot go wrong by saving/restoring all you use.
Dion Hollenbeck (619) 455-5590 x2814
Megatek Corporation, 9645 Scranton Road, San Diego, CA 92121
uunet!megatek!hollen or hollen@megatek.uucp
Technical Details
Message-ID:
<663@megatek.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hp-sdd!megatek!zeta!hollenReferences:
<12324@s.ms.uky.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hp-sdd!megatek!zeta!hollen From: hollen@zeta.megatek.uucp (Dion Hollenbeck) Newsgroups: alt.msdos.programmer,comp.sys.ibm.pc Subject: Re: Calling C functions from assembly Message-ID: <663@megatek.UUCP> Date: 2 Aug 89 14:11:42 GMT References: <12324@s.ms.uky.edu> Sender: news@megatek.UUCP Lines: 84