This is an example program that I am studying so that i can make my own mixed mode assembly/C program.

I am having trouble understanding on the assembly code, why I have to push SI twice at different times and only pop it out once. Also why push and pop DI when it's not used. I am confused from when I have push SI the second time.

/* An example to illustrate C function -> assembly -> a C function.

This program calls the assembly language procedure in file MARKS_A.ASM.

The program outputs min, max, and rounded average of two marks. */

```
#include <stdio.h>
int main(void)
{ int mark1,mark2, min, max, av;
int find_avg(int, int);
extern void stats(int, int, int*, int*, int*);
scanf("%d%d",&mark1,&mark2);
stats(mark1,mark2, &min, &max, &av);
printf("Min = %d, Max = %d, Av = %d\n", min, max, av);
return 0; }
/*********************************************************
* Returns the rounded average required by the assembly
* procedure STATS in file MARKS_A.ASM.*/
int find_avg(int total, int number) {
return((int)((double)total/number + 0.5)); }
```

```
;----------- --------- --------- --------- --------- --------- -
; Assembly program example to show call to a C function.
; This procedure receives a marks array and class size
; and returns minimum, maximum, and rounded average marks.
;----------- --------- --------- --------- --------- --------- -
.MODEL SMALL
EXTRN _find_avg:PROC
.CODE
PUBLIC _stats
_stats PROC
push BP
mov BP,SP
push SI
push DI
mov AX,[BP+4] ; AX := mark1
mov DX,[BP+6] ; DX := mark2
cmp AX,DX ; put min into AX and max into DX
jl next
xchg AX,DX
next:
: mov SI,AX ; SI gets sum
add SI,DX
mov BX,[BP+8] ; return minimum
mov [BX],AX
mov BX,[BP+10] ; return maximum
mov [BX],DX
; now call find_avg C function to compute average
mov AX,2 ;push number of marks
push AX
push SI ;push sum of marks
call _find_avg ; returns average in AX
add SP,4 ; clear stack
mov BX,[BP+12] ; return average
mov [BX],AX
pop DI
pop SI
pop BP
ret ; NOTE calling program clears stack
_stats ENDP
END
```