Homework 8
Array Data Structure/Character Strings/C++ Functions
Overview
In software development, it is not uncommon to mix high-level languages
such as C++ with the power of assembly language where the added implementation
expense of assembly programming is repaid by more efficient execution or
access to specialized hardware operations. Operating systems, language
compilers, hardware drivers, and other specialized applications often have
a mixed high and low-level language component.
In previous discussions we have seen that Assembler, and C may be freely
mixed when parameter passing protocols are strictly followed. These protocols
require some minor changes to the C++ and the Assembler routines. These
changes will be discussed relative to the home work assignment of implementing
several common string routines. Unit testing of these routines will be
done first using a stand alone C and assembly program. System testing will
be done by integrated the routines with an Internet server that plays (badly)
a TicTacToe game. The string functions to be implemented are:
-
Reverse a string.
-
Copy a string.
-
Find the index of one string in another.
-
Find the length of a string.
-
Test for the end of a TicTacToe game.
These string routines will provide practice using processor-level operations
on arrays of strings, and implementing functions that can be called by
a variety of high and low-level languages.
Passing Arrays in Visual C++
Arrays are passed by reference in C++, primarily for efficiency
as only the starting address of the array need be passed rather than all
variables of the array. Since a reference is a pointer, this fits well
with the use of string instructions to implement array operations.
Generally C++ arrays are passed by reference as follows:
C++ Character
Array Passing and Use
| char Array[5];
f(Array);
|
Array db 5 dup(?)
;; byte array
Push
Offset Array
;; Reference to the array
Call f
Add eSp, 4 |
Array db 5 dup(?)
invoke f, addr Array
|
void f( char A[] ) {
A[3] = 'X';
}
|
f Proc
Near
Push eBp
Mov eBp, eSp
Push eSi
Mov eSi, [eBp+8]
Mov [eSi+3], 'X'
; A[3] = 'X'
Pop eSi
Pop eBp
Ret
f Endp |
f Proc
Near C, A : near ptr byte
Push eSi
Mov eSi, A
Mov [eSi+3], 'X' ; A[3] = 'X'
Pop eSi
Ret
f Endp |
C++ Integer
Array Passing and Use
| int Array[5];
f(Array);
|
Array dd 5 dup(?)
;; 32-bit or 4 bytes
Push
Offset Array
;; Array Reference
Call f
Add eSp, 4 |
Array dd 5 dup(?) ;; 32-bit or 4 bytes
invoke f,
addr Array |
void f( int A[] ) {
A[3] = 1234;
}
|
f Proc
Near
Push eBp
Mov eBp, eSp
Push eSi
Mov eSi, [eBp+8]
Mov [eSi+3*4], 1234
; A[3] = 1234
Pop eSi
Pop eBp
Ret
f Endp |
f Proc
Near C, A : near ptr dword
Push eSi
Mov eSi, A
Mov [eSi+3*4], 1234
; A[3] = 1234
Pop eSi
Ret
f Endp |
32 bit Integer Arrays
C++ for 32 bit machines and operating systems such as the Intel Pentium
on Windows or NT, Unix, etc. would typically represent integers as 32 bits
and would also arrays of integers. The following illustrates the memory
representation of an integer array x for either C++ or Assembler. Note
that the above example of passing integer arrays uses a 32 bit array also.
32 Bit Integer Array (Note Assembler definition of array x)
 |
Assignment
The homework consists of two parts. Part 1 is to implement several string
functions in Assembler that are called by a C++ test program. Part
2 is to use these same string functions in an Internet TicTacToe server
program.The minimum points to be completed is 55, additional work up to 70
points will be extra credit.
The point value of each function is listed below in the C++ test program.
-
The C++ and Assembler Test.Cpp program currently works. The steps
to compiling and assembling the test program is given below. Start by following
those steps to verify that you can get the basics to work correctly.
-
30 to 45 points - Translate the C++ functions into Assembler one at a time.
The lower the point value the easier the function should be to write. Generally
you will need to do the following for each function.
-
Delete or comment out the C++ function body code in Test.Cpp (everything
between the { and }) and keep only the C++ prototype.
-
Create a new file for each assembly function. Pattern it after the STRrev.Asm
file given below. You can use the VC++ editor by:
-
Copying the STRrev.Asm file.
-
File | New | Text
-
Paste and edit the file for the changes needed for the new function.
-
File | Save As | Name of the Assembler file (the function name and
file don't have to match).
-
Assemble your new function in MS-DOS.
-
Add the object file from the assembly to the Visual C++ project.
-
Build and execute the project.
-
Verify that the output produced is identical to that from Step 1 below.
-
10 points - An Internet TicTacToe server that uses the string functions
is given in C++. The steps to compiling and assembling the TicTacToe program
is given below. Start by following those steps that verify that you can
get the basic server to work correctly. Then replace the C++ functions
with the Assembler functions that you have written. Verify that it still
works the same.
-
Extra points - Translate other functions or improve the endgame
function to check for ties, etc. The server plays a very weak game, moving
randomly to any open position, add a function that implements a more successful
game playing strategy.
Turn in
-
Cover page - Your name, date, and Homework 8. Staple
all papers together.
-
Assembler Program - All functions you've written. Source listing
rather than assembler output listing.
-
Final C++ Test.Cpp program listing.
-
Final Test.Cpp execution output screen.
-
Final TicTacToe.Cpp program listing.
-
Final TicTacToe.Cpp execution output screen (black screen).
-
Final browser output screen of TicTacToe game.
-
Fileview of TicTacToe project in Visual C++.
How to do the Homework
Download the software
-
Download the self expanding file Hw8.exe
to your computer.
-
From DOS, change directory to where Hw8.exe was downloaded and enter
Hw8.
Or
from Windows Explorer, click on the icon
.
Compiling, Linking and Execution
A Visual C++ project containing two files, Test.Cpp and STRrev.Asm
are in HW8\Test directory. These serve as the starting point for the assignment.
-
A Visual C++ project file name Test.dsw is located in the HW8\Test
directory. In Windows Explorer, click on the icon
.
Note that Visual Studio .NET will need to convert the VC++ 6.0 Test.dsp file.
-
Compile and link Test.Cpp and STRrev.obj, enter:
Build
| Rebuild
-
Execute
-
To execute the program, press F10 key.
-
A black console window will open where input/output is performed. It should
appear exactly as below:
Doing the Assignment
The assignment requires converting some of the C++ functions
into Assembler. Examine the Test.Cpp and STRrev.Asm files
listed below for an example of using C++ and Assembler together.
The steps below are for adding the STRreverse function to the
Test project. Other functions, such as STRlen, etc. would be added
similarly. Once the Assembler function is written, it must be assembled,
and added to the Test project as described below.
-
Create a file named STRrev.Asm in notepad or other text
editor.
-
Copy the assembler listing below and paste into the file named STRrev.Asm.
Save
the file.
-
Open a DOS window and change to the directory where the HW8 files are located,
such as:
cd c:\C335\Hw8
-
Assemble the STRrev.asm file by:
ml /coff /c /Zi /Cp STRrev.asm The
/Cp is necessary because C++ is case sensitive, /Cp preserves case.
-
OBJ: add the STRrev.obj file to the project:
- VC++
- Click View | WorkSpace then select the FileView tab.
- Right click on Test files | Add Files to Project...
- Locate the STRrev.obj file where assembled and add.
- .NET
- Click View | Solution Explorer then select the FileView
tab.
- Right click on Test | Add | Add Existing Item...
- Locate the STRrev.obj file where assembled and add. Because
STRrev.obj is already in the project, it cannot be added again, but this
is how an OBJ file such as STRlen.obj would be added.
-
Compile and link Test.Cpp and STRrev.obj, enter:
Build
| Rebuild
-
Execute
-
To execute the complete program, press F5. To execute one
statement at a time, press F10.
-
A black console window will open where input/output is performed.
Adding a function STRlen.
-
Modify the Test.cpp program by commenting out or deleting all but
the prototype of the STRlen function as follows:
extern "C" int STRlen(char s[])
; /* {
int c = 0;
while(*s++ !=
'\0') c++;
return c;
} */
-
Write the corresponding Assembler code for STRlen following the design
of the STRreverse function.
-
Save the STRlen function in a file in the Hw8 directory, STRlen.asm
is OK but not required.
-
Follow the above instructions for STRlen for Step 4-7.
Stopping
-
Open the black console window and enter Ctrl C keys.
Debugging
-
Step into function - F11.
-
Step around function- F10.
-
Execute to cursor - Put cursor on line and press Ctrl F10.
-
Watch variable - Put cursor over variable or register, or click
right mouse button, then QuickWatch.
-
Stop debugging - Shift F5.
Turn In
-
Cover Page - Your name, date, and Homework 8. Staple all pages together.
-
Output - Screen shot of execution console window.
-
Program - Listing of all assembler functions.
C++ and
Assembler files for Homework 8
;; STRrev.Asm
;; extern "C" void STRreverse( char s1[], char s2[]);
;; Returns - s2 the reversal of s1 (s1 and s2 must not be the same)
;; Registers Altered - eAx, Flags
.386
.model flat, C
option casemap :none ;; Case sensitive
STRlen proto near C, s : near ptr byte
.code ;; void STRreverse(char s1[], char s2[]){
STRreverse Proc Near C, s1 : near ptr byte, s2 : near ptr byte
Push eSi ;; ________
Push eDi ;; |addr s2 | eBp+12
;; |addr s1 | eBp+8
Push s1 ;; |ret addr| eBp+4
Call STRlen ;; |old eBp | eBp+0
Add eSp, 4 ;; |old eSi |
;; |old eDi |
Mov eDi, s2 ;; |________|
Mov eSi, s1 ;; char *eSi=s1+STRlen(s1)-1;
Add eSi, eAx ;; char *eDi=s2;
Dec eSi ;; int eCx=STRlen(s1);
;; char Al;
Mov eCx, eAx ;; do {
;; Al = *eSi--;
@@do: Std ;; *eDi++ = Al;
LodsB ;; } while (--eCx != 0);
Cld ;; }
StosB
Loop @@do
@@endwhile:
Pop eDi
Pop eSi
Ret
STRreverse Endp
End
|
// Test.Cpp
#include <iostream.h>
extern "C" void STRreverse(char s[], char d[]); // Assembly function
// 15 points
// Returns length of string s.
// STRlen("abc"); returns 3
extern "C" int STRlen(char s[]) {
int c = 0;
while(*s++ != '\0') c++;
return c;
}
// 30 points
// Returns index of pattern p in string s or -1 if not found.
// STRindex("456", "01234567"); returns 4
extern "C" int STRindex( char p[], char s[]) {
int pl = STRlen(p), sl = STRlen(s);
int pi = 0, si = 0, last=0;
do {
if(p[pi] == s[si]) {
pi++;
si++;
}
else { pi = 0;
last++;
si = last;
}
} while (pi < pl && si < sl);
if (pi == pl)
return si-pl;
else
return -1;
}
// 15 points
// Copies string s1 to string s2, assumes STRlen(s1) <= STRlen(s2);
// STRcpy(s1, s2); copies s1 to s2
extern "C" void STRcpy(char s1[], char s2[]) {
int i1=0, i2=0;
while( s1[i1] != '\0') s2[i2++] = s1[i1++];
s2[i2] = '\0';
}
// 15 points
// Tests if all 9 positions of TicTacToe board are occupied
// endgame("xoxoxoxox"); returns 1
// endgame("xoxoxoxo8"); returns 0
extern "C" int endgame(char board[]) {
for (int i=0; i<=8; i++)
if (board[i]==(char)(i+'0'))
return 0;
return 1;
}
extern "C" void INTout(int i) {
cout << i;
}
extern "C" void STRout(char s[]) {
cout << s;
}
void main(void) {
char newgame[] = "012345678";
char tiegame[] = "xoxoxoxox";
char dest[10];
STRcpy(newgame, dest);
cout << "STRcpy " << dest << "\n";
STRreverse(newgame, dest);
cout << "STRreverse " << dest << "\n";
cout << "STRlen " << STRlen(newgame) << "\n";
cout << "endgame " << endgame(newgame) << "\n";
cout << "endgame " << endgame(tiegame) << "\n";
cout << "STRindex " << STRindex("456", "01234567");
STRout("\n\n");
}
|
Internet TicTacToe Server
An Internet server program that plays a game of TicTacToe uses the string
functions you have implemented. The server should run on any Windows 95,
98, NT, ME, W2K, XP workstation that has TCP/IP networking installed (if
you can connect to the Internet your machine should work). The string functions
that you have already written and tested can be used by the server by linking
the functions to the server as described below.
When running, the TicTacToe server appears to a browser like a Web server
except the server only will play TicTacToe. A game in progress appears
as below on a Netscape broswer. You would be playing X and making the move
to position 6 to win the game.
TicTacToe Server Overview
The TicTacToe server appears to a browser (IE, Netscape, etc.) just
like any other Web server, except the server is limited to playing TicTacToe.
The browser's purpose is to send a URL to a Web server, the URL
indicates the name of an HTML (Hypertext Markup Language) file that the
Web server should send back., the browser renders or displays the HTML
into something we can read. The browser then sends the server a file name,
gets back HTML from the server, and displays the HTML so people can read
it.
The TicTacToe server is a little different in that it doesn't expect
file names from the browser but instead expects a string that encodes the
TicTacToe board and the next move. In the illustration above, the browser
sends http://localhost/?move=1&board=x12xo567o for a move to
position 1 on a board that has x's in position 0 and 3, and o's in positions
4 and 8. The TicTacToe server reads what the browser sends, placing the
x move in position 1, picking o's move to 5. The server input from the
browser and HTML output sent back to the browser is below:
Browser and TicTacToe Server Interaction and Output

Server Input
GET /?move=2&board=xx2xoo67o HTTP/1.0
Referer: http://localhost/?move=1&board=x12xo567o
Connection: Keep-Alive
User-Agent: Mozilla/4.7 [en] (Win98; I)
Host: localhost
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Server Output
<b>TicTacToe
</b><br>Enter Move X.<pre><form action="" method="GET">
<input type="text" name="move" size=2>
<br>x|x|2
<br>_|_|_
<br>x|o|o
<br>_|_|_
<br>6|7|o
<br></pre>
<input type="hidden" name="board" value="xx2xoo67o"></form>
Ctrl C to stop server
|
TicTacToe Compiling, Linking and Execution
The server is currently written entirely in C++ . To test that it is working
without your assembly functions do the following steps.
-
A Visual C++ project file name TicTacToe.dsw is located in the HW8\TicTacToe
directory. In Windows Explorer, click on the icon
.
Note that Visual Studio .NET will need to translate the VC++ 6.0 Test.dsp file.
-
Compile and link TicTacToe.Cpp, enter:
Build |
Rebuild
-
Execute
-
To execute the complete program, press F5. To execute one
statement at a time, press F10.
-
A black console window will open where cout/cin input/output is
performed. It mainly shows the traffic between the server and browser as
printed from the server. Note that if you have a Web server on the machine
it must be stopped before the TicTacToe server can run.
-
Though the server can run over the Internet, it can also run on a single
machine. Start a Web browser and open to the location localhost
(try 127.0.0.1 if that doesn't work). You should see the start of the game
as below. If a Web server is already running on the machine an error bind()
failed with error 10048 will be displayed. Stop the regular Web server
and execute TicTacToe again.
-
Play the game. The TicTacToe server can be stopped by entering Ctrl
C in the Console window (dark window).
-
The computer plays very badly leaving room for many improvements.
Consider and implement improvements for extra credit.
Doing the Assignment
-
Remove the body of the C++ string function(s) from TicTacToe.Cpp
that you have already written in Assembler for the Test.Cpp program.
They are the same functions in both programs.
-
Add your assembler object files to the TicTacToe project.
They should already assembled and tested and can stay in the original directory
used for testing (e.g. C:\C335\Hw8).
-
Build and execute the TicTacToe server again as before. Note that
only one TicTacToe server can run at a time.
-
From a browser play some TicTacToe, it should behave just as it
did when written purely in C++.
Turn In
-
Output - Screen shot of TicTacToe game being played in browser.
-
Files - Screen shot of Visual C++ showing Fileview of project
files. In the Workspace window of VC++ 6.0 click on the Fileview
tab, or the Solution Explorer window of .NET.
-
Program - Listing of TicTacToe.Cpp after modifications for
assembly functions.
Document last modified: