; ; Procedures written in assembly but called by C ; 16-bit (real mode) version! ; ; C uses the stack to pass parameters, pushing them in reverse order ; ; We use a STANDARD STACK FRAME to access the stack, by PUSHing BP,and ; setting it to SP: ; ; STACK ;-------- ; arg3 (SP+10) ; arg2 (SP+8) ; arg1 (SP+6) ; CS (SP+4) ; IP (BP+2) ; BP (BP=SP) ; ... ; ; The return value is put in ; ; AL - if it's a "char" (byte) ; AX - if it's an "int" (word) ; DX:AX - if it's a "long" (dword) ; Any procedure called by C: ; ; 1) cannot modify ES,DS,SI,DI,BP ; 2) must balance the stack ; 3) must begin with an underscore "_" (name mangling) ; 4) must initialize DS to use its own ASM variables ; ; More examples: ; _MYSUB push bp mov bp,sp push ds ; Save registers mov ax,cs ; Load DS mov dx,ax mov ax,[bp+6] ; Access function parameters sub ax,[bp+8] ; return value in AX pop ds ; Restore registers pop bp retf ; ; int printchar(int num,char c); ; _printchar push bp mov bp,sp .. mov cx, [bp+6] mov dl, [bp+8] ; character occupies lower address top: call dspout loop top .. pop bp retf ; ; int mydiv(long dividend,int divisor); ; ; [BP+8]:[BP+6] - dividend ; [BP+10] - divisor ; _mydiv push bp mov bp,sp .. mov dx,[bp+8] ; example of a dowubleword argument spread mov ax,[bp+6] ; across two stack locations div word [bp+10] ; stack locations can be used as operands .. pop bp retf ; ; char mystr="Hello, how are you today!?$" ; printstr(mystr); ; ; ; void printstr(char *str); ; ; [BP+6] - offset of string to print ; _printstr push bp mov bp,sp ; set standard stack frame .. mov si,[bp+6] ; Offset of message .. PrintLoop: mov dl,[si] ; Read character from [DS:offset] cmp dl,'$' je PrintLoopDone call dspout inc SI jmp PrintLoop .. PringLoopDone: pop bp retf ; ; PrintTheAnswer("fifty-seven"); ; ; ; void PrintTheAnswer(char *str); ; ; Like above, but prepends output with 'The Answer is: ' ; ; [BP+6] - offset of string to print ; OutMessage db 'The Answer is: ',$ _PrintTheAnswer push bp mov bp,sp push ds ; Must preserve default segment in C call mov ax,cs mov ds,ax ; Load default segment for OutMessage mov ax, OutMessage push ax ; Push offset of OutMessage Call _printstr ; Print 'The Answer is: ' pop ax ; cleanup stack pop ds ; restore DS mov ax, [bp+6] push ax Call _printstr ; Print acutal message pop ax pop bp retf