30 likes | 176 Views
8.12 Interfacing C with Assembly Language. main() { asm mov dl,0x30 /* begin counter at ‘0’ */ asm mov ah,2 /* display character function */ next: asm int 0x21 /* DOS call */ asm inc dl /* increment counter */ asm cmp dl,0x3a /* is counter > ‘9’ ? */
E N D
8.12 Interfacing C with Assembly Language main() { asm mov dl,0x30 /* begin counter at ‘0’ */ asm mov ah,2 /* display character function */ next: asm int 0x21 /* DOS call */ asm inc dl /* increment counter */ asm cmp dl,0x3a /* is counter > ‘9’ ? */ asm jnz next } _TEXT segment byte public ‘CODE’ ;main() assume cs:_TEXT _main proc near push bp mov bp,sp ;{ ; asm mov dl,0x30 /* begin counter at ‘0’ */ mov dl,30h ; asm mov ah,2 /* display character function */ mov ah,2 ; next: @1@86: ; asm int 0x21 /* DOS call */ int 21h ; asm inc dl /* increment counter */ inc dl ; asm cmp dl,0x3a /* is counter > ‘9’ ? */ cmp dl,3ah ; asm jnz next jne short @1@86 ;} mov sp,bp pop bp ret _main endp _TEXT ends end TCC -S FILENAME.ASM FILENAME.C Stack area (highest address up), offset address (SS value not shown) and content: written by the program calling “_main” 014E 014D 014C 014B 014A 0149 0148 0147 0146 0145 0144 0143 0142 ... IP high IP low IP high IP low BP high BP low IP high IP low BP high BP low FL high FL low CS high CS low IP high IP low SP when entering _main SP value loaded in BP written when calling INT21H and released by IRET
8.12 Interfacing C with Assembly Language written by the program calling “_main” “_addem”’s BP “_addem”’s variable BP for “_main” parameter passing to “printf” “_main”’s variables parameter passing to “_addem” clearing parameter area after returning from “printf” return address from “_addem” clearing parameter area after returning from “_addem” restoring SP and BP as before “_main” #include <stdio.h> void addem(int x, int y); main() { int a, b; a=5; b=7; addem(a, b); } void addem(int x, int y) { int c; c = x + y; printf (“The sum is %3d\n” , c); } Stack area: TCC -S addem.asm addem.c 014E 014D 014C 014B 014A 0149 0148 0147 0146 0145 0144 0143 0142 0141 0140 013F 013E 013D 013C 013B 013A 0139 0138 0137 0136 0135 0134 0132 0131 ... IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low BP high BP low “c” high “c” low “c” high “c” low “s@” high “s@” low IP high IP low ... IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low BP high BP low “c” high “c” low “c” high “c” low “s@” high “s@” low IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low BP high BP low “c” high “c” low IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low BP high BP low IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low “b” high “b” low “a” high “a” low IP high IP low BP high BP low “a” high “a” low “e” high “e” low “b” high “b” low “d” high “d” low IP high IP low BP high BP low IP high IP low ;void addem(int x, int y) assume cs:_TEXT _addem proc near push bp mov bp,sp ;{ ; int c; sub sp,2 ; c = x + y; mov ax, word prt [bp+4] add ax, word prt [bp+6] mov word prt [bp-2], ax ; printf (“The sum is %3d\n” , c); push word prt [bp-2] mov ax, offset DGROUP:s@ push ax call near ptr _printf pop cx pop cx ;} mov sp,bp pop bp ret _addem endp _TEXT ends _DATA segment word public ‘DATA’ s@ label byte db ‘The sum is %3d’ db 10 db 0 _DATA ends end _TEXT segment byte public ‘CODE’ ;main() assume cs:_TEXT _main proc near push bp mov bp,sp ;{ ; int a, e, b, d; sub sp,8 ; a=5; mov word prt [bp-2], 5 ; b=7; mov word prt [bp-6], 7 ; addem(a, b); push word prt [bp-6] push word prt [bp-2] call near ptr _addem pop cx pop cx ;} mov sp,bp pop bp ret _main endp
8.12 Interfacing C with Assembly Language #include <stdio.h> extern int xplusy(int x,int y) main() { int a, b; a=5; b=7; printf(“The sum is %d\n”xplusy(a,b)); } C program calling assembler routine “xplusy” Assembled “xplusy” .MODEL SMALL,C 0000 .CODE PUBLIC xplusy 0000 xplusy PROC NEAR C,x:WORD,y:WORD LOCAL z:WORD 0006 8B 46 04 MOV AX,x ;load x value into AX 0009 03 46 06 ADD AX,y ;add value of y to AX 000C 89 46 FE MOV z,AX ;store AX in z RET 0013 xplusy ENDP END Stack area used to pass parameters to “xplusy” assembler subroutine: 014E 014D 014C 014B 014A 0149 0148 0147 0146 0145 0144 0143 0142 ... 00 07 00 05 IP high IP low BP high BP low 00 07 00 05 IP high IP low 00 07 00 05 IP high IP low BP high BP low 00 0C “b” and “a” passed by “main” return to “main” address Linked “xplusy” SP when entering “xplusy” 2755:0020 55 PUSH BP 2755:0021 8BEC MOV BP,SP 2775:0023 83C4FE ADD SP,FE 2775:0026 8B4604 MOV AX,WORD PTR [BP+04] 2775:0029 034606 ADD AX,WORD PTR [BP+06] 2775:002C 8946FE MOV WORD PTR [BP-02],AX 2775:002F 8BE5 MOV SP,BP 2775:0031 5D POP BP 2775:0032 C3 RET SP value loaded in BP reserved for “z”