home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: sparky!uunet!munnari.oz.au!titan!trlluna!bruce.cs.monash.edu.au!monu6!giaeb!s1110238
- From: s1110238@giaeb.cc.monash.edu.au (Lee Hollingworth)
- Subject: Re: Help with ASM/C interface
- Message-ID: <s1110238.722388720@giaeb>
- Sender: news@monu6.cc.monash.edu.au (Usenet system)
- Organization: Monash University, Melb., Australia.
- References: <ad#@byu.edu>
- Date: Sat, 21 Nov 1992 23:32:00 GMT
- Lines: 123
-
- curtisn@SAS (Curtis Nelson) writes:
-
- >I have a question I hope one of you can help me with. I'm using Borland C++
- >3.0 and I am trying to write a simple assembly language routine in my code.
-
- Embedded assembly code in a C function?
-
- If so there is no problem, you simply use your C variables.
-
- Example (written in MSC format BC should not be too different);
-
- int write_port(unsigned char ch, int port)
- {
- _asm {
- mov ah, 01h
- mov ah, ch
- mov dx, port
- int 14h
- }
- }
-
- The return value of the int 14h function is in AX, and is automatically
- returned by the asm code. You can be more explicit by adding in a variables.
-
- int write_port(unsigned char ch, int port)
- {
- int status;
-
- _asm {
- mov ah, 01h
- mov ah, ch
- mov dx, port
- int 14h
- mov status, ax
- }
-
- return status & 0x80; /* status of write */
- }
-
- >My question is, how do I pass vaues back and forth? For example, if I push
- >a value onto the stack in assembly, how con I retrieve that value from C? I
- >know I can use the stack, but how do I access an item on the stack? I've
- >looked at 'pop', but that appears to only work in C++, and I'm writing this
- >in straight C.
-
- If you are interfacing with assembly code in a mixed language environment
- you access parameters passed to the asm code by calculating the offset from
- bp. Generally this is equal to 2 + size of return address + total size of
- parameters between bp and the parameter you are trying to access.
-
- Eg, a FAR procedure that has received one parameter with a four-byte address.
-
- displacement = 2 + size of return address
- = 2 + 4
- = 6
-
- To load the parameter into a register you then would use,
-
- mov bx, [bp+6]
-
- or you can define your own parameter names in your code such as,
-
- foo EQU [bp+6]
-
- then to access foo it is simply,
-
- mov bx, foo
-
- Returning values from asm code is simple if the return data type size is
- four bytes or less.
-
- Data Size Returned in
- 1 AL
- 2 AX
- 4 High byte DX Low byte AX
-
- If the value to be returned is greater than 4 bytes, your C function must
- allocate space for the return value, and place the address of that space
- in DX:AX.
-
- Here is a simple source file for some C - ASM interface code...
-
- ;--------------------------------------------------------------------------
- key_ready equ 11h ; function K_READY
-
- .model small
- .code
- public _prnwrite
- ;------------------------- prnwrite ----------------------------------------
- ; call unsigned int prnwrite(ch, port);
- ; unsigned char ch
- ; unsigned int port
- ; refer to biosibm.h for defines
- ; returns status in ah
- ;----------------------------------------------------------------------------
- _prnwrite proc
- push bp
- mov bp, sp ; mov stack pointer to base pointer
- push si
- push di
-
- mov al, [bp+4] ; get character to print
- mov dx, [bp+6] ; get port number
- mov ah, 00h
- int 17h
- xor al, al ; clear al, ah returned
-
- pop di
- pop si
- pop bp
- ret
- _prnwrite endp
-
- end
- ;-------------------------------------------------------------------------
-
- >I would appreciate any help!
-
- I think you would get more help if you used the comp.os.msdos.programmer
- newsgroup.
-
- Lee Hollingworth
- s1110238@giaeb.cc.monash.edu.au
-