assembly code
assign.txt
COSC 2325 C++ calling external assembler function. Use the posted C++ program: Do not modify or change the C++ program. Write in assembly language, created in a in a separate file named labxx.asm, where xx is the lab number (01, 02, 03…) the external assembler function AverageFunc. The first parameter is the number of elements in the array and the address of the array is the second parameter. For this assignment: The stack must managed directly by the assembler code No masm directives can be used to manage the stack The masm function is called by the C++ program using the decl C style stack model The masm function must do all its responsibilities for a decl C style stack mdel The stack parameters must be accessed from the stack using [BP + stack offset] addressing style. The function will determine the average of the values in the array and return the average rounded to the nearest whole number. So, if the fractional part of the result is >= 0.5, the result is rounded to the next integer number. If not, then the integer part of the number is used as the result. See the posted video tutorial blackboard to see a demonstration of how to configure Visual Studio 2013 (and 2012) to build and link a C++ program that calls an assembler function.
AverageFuncCnASM.cpp
AverageFuncCnASM.cpp
#include
"stdafx.h"
#include
<
iostream
>
#include
<
cstdint
>
using
namespace
std
;
uint32_t array1ui32
[]
=
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
};
uint32_t array1Elementui32
=
sizeof
(
array1ui32
)
/
sizeof
(
array1ui32
[
0
]);
uint32_t array2ui32
[]
=
{
111
,
222
,
333
,
444
,
555
,
666
,
777
,
888
,
999
,
1000
};
uint32_t array2Elementui32
=
sizeof
(
array2ui32
)
/
sizeof
(
array2ui32
[
0
]);
extern
"C"
{
uint32_t
AverageFunc
(
uint32_t
,
uint32_t
[]);
}
int
_tmain
(
int
argc
,
_TCHAR
*
argv
[])
{
cout
<<
"Array 1 Average : "
<<
AverageFunc
(
array1Elementui32
,
array1ui32
)
<<
endl
;
cout
<<
"Array 2 Average : "
<<
AverageFunc
(
array2Elementui32
,
array2ui32
)
<<
endl
;
}
source.asm
.586 ;Target processor, use Pentium class machines .MODEL FLAT, C ;Use the flat memory model. Use C calling and return conventions .STACK ;Define a stack segment of 1KB (Not required for this example) .DATA ;Create a near data segment. Local variables are declared here (Not required for this example) .CODE ;Indicates the start of a code segment. AverageFunc PROC NoOfElemenstsDW EQU 08 ArrayAddrStartPtr EQU 12 ElementSize EQU Type DWORD push ebp ;save curent stack frame pointer mov ebp, esp ;set current stack frame pointer push esi ;perserve registers for calling program push ecx push edx push ebx ;get parameters from stack using stack frame into dedicated registers ;ecx set as NoOfElemenstsDW ;esi set as index pointer ;process the array sum sub eax,eax ;clear summer arrayLoop: ; sum into summer ; update index pointer to next element loop arrayLoop ;take average and calcuate rounding ;clear upper dividend ; set divisor from stackset ;edx:eax / ebx ;multiply remainder by 2 ;if 2 x remainder is greater or equal than divisor jb NoRound ; round quotient up to next integer NoRound: ;endif ; restore used registers ;retore calling bp frame ret AverageFunc ENDP END