15.07.2014 Views

AM2: Protected-Mode Programming

AM2: Protected-Mode Programming

AM2: Protected-Mode Programming

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

<strong>AM2</strong>: <strong>Protected</strong>-<strong>Mode</strong> <strong>Programming</strong><br />

Duration: 3 hours<br />

Components: Lab exercises and report.<br />

Objectives:<br />

(a) To examine how protected-mode programming is done on x86 based computer.<br />

(b) To evaluate the advantages of protected-mode programming compared to real-mode<br />

programming in x86 microprocessor.<br />

(c) To develop protected-mode assembly language programs which utilize the floatingpoint<br />

unit (FPU) on x86 based computer.<br />

(d) To develop Win32 Console programs based on x86 assembly language.<br />

1. Floating-Point Unit<br />

The Intel 8086 processor was designed to handle only integer arithmetic. This turned out to<br />

be a problem for graphics and calculation-intensive software using floating-point calculations.<br />

It was possible to emulate floating-point arithmetic purely through software, but the<br />

performance penalty was severe. Programs such as AutoCad (by Autodesk) demanded a more<br />

powerful way to perform floating-point math. Intel sold a separate floating-point coprocessor<br />

chip named the 8087, and upgraded it along with each processor generation. Beginning from<br />

Intel 80486, the floating-point hardware was integrated into the processor and known as the<br />

floating-point unit (FPU).<br />

1.1 FPU Register Stack<br />

The FPU does not use the general-purpose registers (EAX, EBX, etc.). Instead, it has its own<br />

set of registers called a register stack. It loads values from memory into the register stack,<br />

performs calculations, and stores stack values into memory. FPU instructions evaluate<br />

mathematical expressions in postfix format. The following, for example, is called an infix<br />

expression: (5 * 6) + 4. The postfix equivalent is<br />

5 6 * 4 +<br />

The infix expression (A + B) * C requires parenthesis to override the default precedence<br />

rules (multiplication before addition). The parenthesis is not required in the equivalent postfix<br />

expression:<br />

A B + C *<br />

1.1.1 Expression Stack<br />

A stack holds intermediate values during the evaluation of postfix expressions. Figure 1.1<br />

shows the steps required to evaluate the postfix expression 5 6 * 4 –. The stack entries are<br />

labelled ST(0) and ST(1), with ST(0) indicating where the stack pointer would normally be<br />

pointing.<br />

Page 1 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Figure 1.1: Evaluating the Postfix Expression 5 6 * 4 – .<br />

Table 1.1 contains some examples of translating infix to equivalent postfix expressions.<br />

Table 1.1 Infix to Postfix Examples<br />

Infix<br />

Postfix<br />

A + B A B +<br />

(A - B) / D A B - D /<br />

(A + B) * (C + D) A B + C D + *<br />

((A + B) / C) * (E - F) AB + C / EF - *<br />

1.2 FPU Data Registers<br />

The FPU has eight individually addressable 80-bit data registers named R0 through R7 (see<br />

Figure 2). Together, they are called a register stack. A three-bit field named TOP in the FPU<br />

status word identifies the register number that is currently the top of the stack. In Figure 1.2,<br />

for example, TOP equals binary 011, identifying R3 as the top of the stack. This stack<br />

location is also known as ST(0) (or simply ST) when writing floating-point instructions. The<br />

last register is ST(7).<br />

Figure 1.2: Floating-Point Data Register Stack.<br />

As we might expect, a push operation (also called load) decrements TOP by 1 and copies an<br />

operand into the register identified as ST(0). If TOP equals 0 before a push, TOP wraps<br />

around to register R7. A pop operation (also called store) copies the data at ST(0) into an<br />

operand, then adds 1 to TOP. If TOP equals 7 before the pop, it wraps around to register R0.<br />

Page 2 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

If loading a value into the stack would result in overwriting existing data in the register stack,<br />

a floating-point exception is generated. Figure 1.3 shows the same stack after 1.0 and 2.0<br />

have been pushed (loaded) on the stack.<br />

Figure 1.3: FPU Stack after Pushing 1.0 and 2.0.<br />

Although it is interesting to understand how the FPU implements the stack using a limited set<br />

of registers, we need only focus on the ST(n) notation, where ST(0) is always the top of stack.<br />

From this point forward, we refer to stack registers as ST(0), ST(1), and so on. Instruction<br />

operands cannot refer directly to register numbers.<br />

Floating-point values in registers use the IEEE 10-byte extended real format (also known as<br />

temporary real). When the FPU stores the result of an arithmetic operation in memory, it<br />

translates the result into one of the following formats: integer, long integer, single precision<br />

(short real), double precision (long real), or packed binary-coded decimal (BCD).<br />

1.3 Floating-Point Instruction Set<br />

The FPU instruction set is somewhat complex, so we will attempt here to give you an<br />

overview of its capabilities, along with specific examples that demonstrate code typically<br />

generated by compilers. In addition, we will see how you can exercise control over the FPU<br />

by changing its rounding mode. The instruction set contains the following basic categories of<br />

instructions:<br />

• Data transfer<br />

• Basic arithmetic<br />

• Comparison<br />

• Transcendental<br />

• Load constants (specialized predefined constants only)<br />

• x87 FPU control<br />

• x87 FPU and SIMD state management<br />

Floating-point instruction names begin with the letter F to distinguish them from CPU<br />

instructions. The second letter of the instruction mnemonic (often B or I) indicates how a<br />

memory operand is to be interpreted: B indicates a BCD operand, and I indicates a binary<br />

integer operand. If neither is specified, the memory operand is assumed to be in real-number<br />

format. For example, FBLD operates on BCD numbers, FILD operates on integers, and FLD<br />

operates on real numbers.<br />

Page 3 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

1.3.1 Operands<br />

A floating-point instruction can have zero operands, one operand, or two operands. If there<br />

are two operands, one must be a floating-point register. There are no immediate operands, but<br />

certain predefined constants (such as 0.0, _and log2 10) can be loaded into the stack.<br />

General-purpose registers such as EAX, EBX, ECX, and EDX cannot be operands. (The only<br />

exception is FSTSW, which stores the FPU status word in AX.) Memory-to-memory<br />

operations are not permitted. Integer operands must be loaded into the FPU from memory<br />

(never from CPU registers); they are automatically converted to floating-point format.<br />

Similarly, when storing floating-point values into integer memory operands, the values are<br />

automatically truncated or rounded into integers.<br />

1.3.2 Initialization (FINIT)<br />

The FINIT instruction initializes the FPU. It sets the FPU control word to 037Fh, which<br />

masks (hides) all floating-point exceptions, sets rounding to nearest even, and sets the<br />

calculation precision to 64 bits. We recommend calling FINIT at the beginning of your<br />

programs, so you know the starting state of the processor.<br />

1.3.3 Floating-Point Data Types<br />

Let’s quickly review the floating-point data types supported by MASM (QWORD, TBYTE,<br />

REAL4, REAL8, and REAL10), listed in Table 1.2. You will need to use these types when<br />

defining memory operands for FPU instructions. For example, when loading a floating-point<br />

variable into the FPU stack, the variable is defined as REAL4, REAL8, or REAL10:<br />

.data<br />

bigVal REAL10 1.212342342234234243E+864<br />

.code<br />

fld bigVal ; load variable into stack<br />

Table 1.2: Intrinsic Data Types.<br />

Type Usage<br />

QWORD 64-bit integer<br />

TBYTE 80-bit (10-byte) integer<br />

REAL4 32-bit (4-byte) IEEE short real<br />

REAL8 64-bit (8-byte) IEEE long real<br />

REAL10 80-bit (10-byte) IEEE extended real<br />

1.3.4 Reading and Writing Floating-Point Values<br />

In this experiment, the following two procedures for floating-point input-output (created by<br />

William Barrett of San Jose State University) are used:<br />

ReadFloat: Reads a floating-point value from the keyboard and pushes it on the floatingpoint<br />

stack. It accepts a wide variety of floating-point formats. Some examples<br />

are shown below:<br />

35 3.5E005<br />

+35. -3.5E+5<br />

-3.5 3.5E-4<br />

.35 +3.5E-4<br />

3.5E5<br />

WriteFloat: Writes the floating-point value at ST(0) to the console window in exponential<br />

format.<br />

ShowFPUStack: Another useful procedure, written by James Brink of Pacific Lutheran<br />

University, displays the FPU stack. It is called with no parameters:<br />

call ShowFPUStack<br />

Page 4 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Example 1.1<br />

The following example program pushes two floating-point values on the FPU stack, displays<br />

it, inputs two values from the user, multiplies them, and displays their product:<br />

Note: Please refer to Appendix A on how to build and run this program.<br />

Sample input/output (user input shown in bold type):<br />

------ FPU Stack ------<br />

ST(0): +1.0000000E+001<br />

ST(1): +1.2345600E+002<br />

Please enter a real number: 3.5<br />

Please enter a real number: 4.2<br />

Their product is: +1.4700000E+001<br />

Example 1.2<br />

Let’s code the expression valD = -valA + (valB * valC). A possible step-by-step solution is:<br />

Load valA on the stack and negate it. Load valB into ST(0), moving valA down to ST(1).<br />

Multiply ST(0) by valC, leaving the product in ST(0). Add ST(1) and ST(0) and store the<br />

sum in valD:<br />

Page 5 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Please refer to Appendix B on how to debug this program.<br />

Exercise 1.1<br />

Write a program that prompts the user for the radius of a circle. Calculate and display the<br />

circle’s circumference and area. Use the ReadFloat and WriteFloat procedures. Use the<br />

FLDPI instruction to load onto the register stack. Please refer to Appendix A on how to<br />

create, build and run your program.<br />

Exercise 1.2<br />

Write a program that asks the user to enter the X and Y coordinates of two points on a<br />

straight line. Calculate and display the gradient of the straight line. Use the ReadFloat and<br />

WriteFloat procedures in your program.<br />

2. Win32 Console <strong>Programming</strong><br />

On the surface, 32-bit console mode programs look and behave like 16-bit MS-DOS<br />

programs running in text mode. There are differences, however: The former runs in 32-bit<br />

protected mode, whereas MS-DOS programs run in real-address mode. They use different<br />

function libraries. Win32 programs call functions from the same library used by graphical<br />

Windows applications. MS-DOS programs use BIOS and MS-DOS interrupts that have<br />

existed since the introduction of the IBM-PC.<br />

2.1 Application <strong>Programming</strong> Interface<br />

An Application <strong>Programming</strong> Interface (API) is a collection of types, constants, and<br />

functions that provide a way to directly manipulate objects through programming. Therefore,<br />

the Win32 API lets you tap into the functions in the 32-bit version of MS-Windows. The<br />

Irvine32 link library used in this experiment is completely built on Win32 console functions.<br />

It is compatible with Win32 API functions and can be used for basic input output, simulations,<br />

timing, and other useful operations. Table 2.1 gives a complete list of procedures in the<br />

Irvine32 link library.<br />

Table 2.1: Procedures in the Irvine32 link library<br />

Procedure<br />

Description<br />

CloseFile<br />

Closes a disk file that was previously opened.<br />

Clrscr<br />

Clears the console window and locates the cursor at the upper left corner.<br />

CreateOutputFile Creates a new disk file for writing in output mode.<br />

Crlf<br />

Writes an end-of-line sequence to the console window.<br />

Delay<br />

Pauses the program execution for a specified n -millisecond interval.<br />

DumpMem<br />

Writes a block of memory to the console window in hexadecimal.<br />

DumpRegs<br />

Displays the EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EFLAGS, and EIP<br />

registers in hexadecimal. Also displays the most common CPU status flags.<br />

GetCommandTail Copies the program’s command-line arguments (called the command tail)<br />

into an array of bytes.<br />

Page 6 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

GetDateTime<br />

GetMaxXY<br />

GetMseconds<br />

GetTextColor<br />

Gotoxy<br />

IsDigit<br />

MsgBox<br />

MsgBoxAsk<br />

OpenInputFile<br />

ParseDecimal32<br />

ParseInteger32<br />

Random32<br />

Randomize<br />

RandomRange<br />

ReadChar<br />

ReadDec<br />

ReadFromFile<br />

ReadHex<br />

ReadInt<br />

ReadKey<br />

ReadString<br />

SetTextColor<br />

Str_compare<br />

Str_copy<br />

Str_length<br />

Str_trim<br />

Str_ucase<br />

WaitMsg<br />

WriteBin<br />

WriteBinB<br />

WriteChar<br />

WriteDec<br />

WriteHex<br />

WriteHexB<br />

WriteInt<br />

WriteStackFrame<br />

WriteStackFrameName<br />

WriteString<br />

WriteToFile<br />

WriteWindowsMsg<br />

Gets the current date and time from the system.<br />

Gets the number of columns and rows in the console window’s buffer.<br />

Returns the number of milliseconds elapsed since midnight.<br />

Returns the active foreground and background text colors in the console<br />

window.<br />

Locates the cursor at a specific row and column in the console window.<br />

Sets the Zero flag if the AL register contains the ASCII code for a decimal<br />

digit (0–9).<br />

Displays a popup message box.<br />

Display a yes/no question in a popup message box.<br />

Opens an existing disk file for input.<br />

Converts an unsigned decimal integer string to 32-bit binary.<br />

Converts a signed decimal integer string to 32-bit binary.<br />

Generates a 32-bit pseudorandom integer in the range 0 to FFFFFFFFh.<br />

Seeds the random number generator with a unique value.<br />

Generates a pseudorandom integer within a specified range.<br />

Waits for a single character to be typed at the keyboard and returns the<br />

character.<br />

Reads an unsigned 32-bit decimal integer from the keyboard, terminated by<br />

the Enter key.<br />

Reads an input disk file into a buffer.<br />

Reads a 32-bit hexadecimal integer from the keyboard, terminated by the<br />

Enter key.<br />

Reads a 32-bit signed decimal integer from the keyboard, terminated by the<br />

Enter key.<br />

Reads a character from the keyboard’s input buffer without waiting for<br />

input.<br />

Reads a string from the keyboard, terminated by the Enter key.<br />

Sets the foreground and background colors of all subsequent text output to<br />

the console.<br />

Compares two strings.<br />

Copies a source string to a destination string.<br />

Returns the length of a string in EAX.<br />

Removes unwanted characters from a string.<br />

Converts a string to uppercase letters.<br />

Displays a message and waits for a key to be pressed.<br />

Writes an unsigned 32-bit integer to the console window in ASCII binary<br />

format.<br />

Writes a binary integer to the console window in byte, word, or doubleword<br />

format.<br />

Writes a single character to the console window.<br />

Writes an unsigned 32-bit integer to the console window in decimal format.<br />

Writes a 32-bit integer to the console window in hexadecimal format.<br />

Writes a byte, word, or doubleword integer to the console window in<br />

hexadecimal format<br />

Writes a signed 32-bit integer to the console window in decimal format.<br />

Writes the current procedure’s stack frame to the console.<br />

Writes the current procedure’s name and stack frame to the console.<br />

Writes a null-terminated string to the console window.<br />

Writes a buffer to an output file.<br />

Displays a string containing the most recent error generated by MS-<br />

Windows.<br />

Page 7 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Some of the procedures that are used in this experiment are described in the following<br />

sections.<br />

2.1.1 MsgBox<br />

The MsgBox procedure displays a graphical popup message box with an optional caption.<br />

(This works when the program is running in a console window.) Pass it the offset of a string<br />

in EDX, which will appear in the inside the box. Optionally, pass the offset of a string for the<br />

box’s title in EBX. To leave the title blank, set EBX to zero. Sample call:<br />

.data<br />

caption db "Dialog Title", 0<br />

HelloMsg<br />

.code<br />

mov ebx,OFFSET caption<br />

mov edx,OFFSET HelloMsg<br />

call MsgBox<br />

Sample output:<br />

BYTE "This is a pop-up message box.", 0dh,0ah<br />

BYTE "Click OK to continue...", 0<br />

2.1.2 MsgBoxAsk<br />

The MsgBoxAsk procedure displays a graphical popup message box with Yes and No<br />

buttons. (This works when the program is running in a console window.) Pass it the offset of<br />

a question string in EDX, which will appear in the inside the box. Optionally, pass the offset<br />

of a string for the box’s title in EBX. To leave the title blank, set EBX to zero. MsgBoxAsk<br />

returns an integer in EAX that tells you which button was selected by the user. The value will<br />

be one of two predefined Windows constants: IDYES (equal to 6) or IDNO (equal to 7).<br />

Sample call:<br />

.data<br />

caption BYTE "Survey Completed",0<br />

question<br />

BYTE "Thank you for completing the survey."<br />

BYTE 0dh,0ah<br />

BYTE "Would you like to receive the results?",0<br />

.code<br />

mov ebx,OFFSET caption<br />

mov edx,OFFSET question<br />

call MsgBoxAsk<br />

;(check return value in EAX)<br />

Page 8 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Sample output:<br />

2.1.3 ReadString<br />

The ReadString procedure reads a string from the keyboard, stopping when the user presses<br />

the Enter key. Pass the offset of a buffer in EDX and set ECX to the maximum number of<br />

characters the user can enter, plus 1 (to save space for the terminating null byte). The<br />

procedure returns the count of the number of characters typed by the user in EAX.<br />

Sample call:<br />

.data<br />

buffer BYTE 21 DUP(0) ; input buffer<br />

byteCount DWORD ? ; holds counter<br />

.code<br />

mov edx,OFFSET buffer ; point to the buffer<br />

mov ecx,SIZEOF buffer ; specify max characters<br />

call ReadString ; input the string<br />

mov byteCount,eax ; number of characters<br />

ReadString automatically inserts a null terminator in memory at the end of the string. The<br />

following is a hexadecimal and ASCII dump of the first 8 bytes of buffer after the user has<br />

entered the string “ABCDEFG”:<br />

41 42 43 44 45 46 47 00 ABCDEFG<br />

The variable byteCount equals 7.<br />

2.1.4 WriteString<br />

The WriteString procedure writes a null-terminated string to the console window. Pass the<br />

string’s offset in EDX. Sample call:<br />

.data<br />

prompt BYTE "Enter your name: ",0<br />

.code<br />

mov edx,OFFSET prompt<br />

call WriteString<br />

2.1.5 WriteDec<br />

The WriteDec procedure writes a 32-bit unsigned integer to the console window in decimal<br />

format with no leading zeros. Pass the integer in EAX. Sample call:<br />

mov eax,295<br />

call WriteDec ; displays: "295"<br />

2.1.6 WriteToFile<br />

The WriteToFile procedure writes the contents of a buffer to an output file. Pass it a valid file<br />

handle in EAX, the offset of the buffer in EDX, and the number of bytes to write in ECX.<br />

When the procedure returns, if EAX is greater than zero, it contains a count of the number of<br />

bytes written; otherwise, an error occurred. The following code calls WriteToFile:<br />

Page 9 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

BUFFER_SIZE = 5000<br />

.data<br />

fileHandle DWORD ?<br />

buffer BYTE BUFFER_SIZE DUP(?)<br />

.code<br />

mov eax,fileHandle<br />

mov edx,OFFSET buffer<br />

mov ecx,BUFFER_SIZE<br />

call WriteToFile<br />

The following pseudocode describes how to handle the value returned in EAX after calling<br />

WriteToFile:<br />

if EAX = 0 then<br />

error occurred when writing to file<br />

call WriteWindowsMessage to see the error<br />

else<br />

EAX = number of bytes written to the file<br />

endif<br />

Example 2<br />

The following program creates a file in output mode, asks the user to enter some text, writes<br />

the text to the output file, reports the number of bytes written, and closes the file. It checks<br />

for errors after attempting to create the file:<br />

Page 10 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Note: Please refer to Appendix A on how to create, build and run this program<br />

Exercise 2.1<br />

Modify the program in Example 2 so that it will display a graphical popup message box to<br />

ask the user whether the text file should be created. If the user selects “Yes”, the text file is<br />

created and the program terminates. Otherwise, the program will terminate directly.<br />

Exercise 2.2<br />

Write a program that performs the following operations:<br />

i. Create a new text file.<br />

ii. Prompt the user for a student identification number, name, and date of birth.<br />

iii. Display a graphical popup message box to ask the user if there are more data.<br />

iv. If there are, allow the user to enter the new data and go back to step (iii).<br />

v. Otherwise, write all data to the text file and exit the program.<br />

References<br />

1. Kip R. Irvine, “Assembly Language for x86 Processors”, 6 th Edition, Prentice-Hall<br />

Inc., U.S.A., 2010.<br />

2. Kip R. Irvine, Assembly Language for x86 Processors, 6 th Edition [Online]. Available:<br />

http://kipirvine.com/asm/<br />

Important Note:<br />

Lab assessment will be carried out during the lab session. It is the student's responsibility to<br />

complete the given tasks and report to the lab instructors for assessment.<br />

(END)<br />

Page 11 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Appendix A<br />

Opening a project<br />

Visual Studio and Visual C++ Express require assembly language source files to belong to a<br />

project, which is a kind of container. A project holds configuration information such as the<br />

locations of the assembler, linker, and required libraries. A project has its own folder, and it<br />

holds the names and locations of all files belonging to it. We have created a sample project<br />

folder in the c:\ECP4166\<strong>AM2</strong>\Example\Project_Sample directory, and its name is Project.<br />

Do the following steps, in order:<br />

i. Start Visual Studio or Visual C++ Express.<br />

ii. First you will open an existing Visual Studio project file. If you're using Visual Studio,<br />

select Open Project from the File menu. Or, if you're using Visual C++ Express,<br />

select Open, and select Project/Solution.<br />

iii. Navigate to the c:\ECP4166\<strong>AM2</strong>\Example\Project_Sample folder and open the file<br />

named Project.sln.<br />

iv. In the Solution Explorer window, you will see the word Project. This is the name of<br />

a Visual Studio project.<br />

v. Next, you need to add the source code file (.asm) to the project. To do that, right-click<br />

on Project, select Add, select Existing Item, select the main.asm file, and click the<br />

Add button to close the dialog window. (You can use this sequence of commands in<br />

the future to add any asm file into a project.)<br />

vi. Next, you will open the main.asm file for editing. Double-click the main.asm file to<br />

open it in the editing window. (Visual Studio users may see a popup dialog asking for<br />

the encoding method used in the asm file. just click the OK button to continue.)<br />

Build the Program<br />

Next, you will build (assemble and link) the sample program. Select Build Project from the<br />

Build menu. You should see messages indicating the build progress in the Output window for<br />

Visual Studio at the bottom of the screen. If you do not see these messages, the project has<br />

probably not been modified since it was last built. No problem--just select Rebuild Project<br />

from the Build menu.<br />

Run the Program<br />

Select Start without Debugging from the Debug menu. The following console window<br />

should appear, although your window will be larger than the one shown here:<br />

Creating New Projects of Your Own<br />

Before long, you will want to create your own projects. The easiest way to do this is to copy<br />

the entire c:\ECP4166\<strong>AM2</strong>\Examples\Project_Sample folder to a new location. Copy it to<br />

a folder in which you have read/write permissions.<br />

Page 12 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Appendix B<br />

Microsoft Visual Studio 2008 Debugger<br />

This debugger lets you do the following:<br />

Step through your program, viewing the source code<br />

Set breakpoints in your code<br />

View CPU registers and flags<br />

View a disassembly of your program<br />

Watch the values of program variables<br />

View the runtime stack<br />

Display blocks of memory<br />

Perform remote debugging across a network<br />

Open the Visual Studio Project file<br />

1. Go to the the folder in your computer that contains the project. You may use the<br />

sample project located at c:\ECP4166\<strong>AM2</strong>\Example\Project_Sample.<br />

2. Double-click the file named Project.sln.<br />

3. If there is already an asm file in the project, right-click on the asm file and<br />

select Remove in the Solution Explorer window. When prompted by a dialog window,<br />

click the Remove button.<br />

4. Right-click Project in the same window, select Add, and select Existing Item.<br />

5. Select your asm file. It will be added to your project.<br />

6. Select Save All from the File menu to save your project settings.<br />

7. Double-click your asm file in Solution Explorer to open it in the editor.<br />

Debugger Windows<br />

The debugging information is shown in the following windows after the debugger is<br />

invokved (press the F10 key). You can remove any debugger window by right-clicking on its<br />

Tab and selecting Hide. You can open any debugger window by selecting Windows from the<br />

Debug menu.<br />

Source Window<br />

The Source window displays the program's source file. Note that the first instruction has a<br />

yellow arrow next to it. The arrow always indicates the next instruction that is about to<br />

execute.<br />

Watch Window<br />

Select Windows from the Debug menu, and select Watch 1. A Watch window is like an<br />

electronic spreadsheet that displays the names and values of selected variables. As you step<br />

through a program, you can see variables in this window change value. Currently the window<br />

is empty, but you can drag any program variable into the window with your mouse.<br />

Click on the tab at the bottom of the screen labeled Watch 1 to bring it to the front. Drag the<br />

variables into the Watch window and note their current values. The values are currently<br />

displayed in decimal. You may select other format by right-clicking on the watch window<br />

and selecting the desired format from the popup menu.<br />

Page 13 of 14


ECP4166: Advanced Microprocessors<br />

<strong>AM2</strong><br />

Memory Window<br />

Select Windows from the Debug menu, and select Memory. The Memory window displays a<br />

raw dump of memory in either hexadecimal or decimal. It is particularly useful when<br />

working with array variables. For e.g., it can display the value of valD by typing &valD next<br />

to the Address label.<br />

The & before the variable name means to interpret the variable name as an address. In<br />

assembly language, all labels are implied addresses. Variable names are case-sensitive in the<br />

debugger.<br />

The Memory window displays a series of individual memory bytes, beginning at the address<br />

of valD. Right-click on the window, and select 64-bit Floating Point. Along the left side of<br />

the window is shown the address of the first value in each line.<br />

Register Window<br />

Select Windows from the Debug menu, and select Register. The Register window displays<br />

the contents of the CPU registers. The floating-point register stack and flag values are not<br />

shown by default, but you can add them by right-click in the Register window and select<br />

Floating Point and Flags, respectively.<br />

Debugging Program<br />

Step Over (F10)<br />

Pressing the F10 function key will single-step through the program. As you press F10, watch<br />

the yellow arrow in the Source window move from statement to statement. Notice the<br />

following as you step through the program:<br />

Individual register names (in the Register window) turn red, indicating that they have been<br />

modified. Variables in the Watch window turn red when they are modified. Memory<br />

locations in the Memory window turn red when they are modified. As soon as you reach the<br />

exit statement and press F10, the debugger halts.<br />

Step Into (F11)<br />

Another way to step through a program is to use the Trace (F11) command. It steps down into<br />

procedure calls. In contrast, the F10 key just executes procedure calls without tracing into the<br />

procedure code.<br />

Stopping and Restarting<br />

It's easy to either stop or restart your program inside the debugger while you're in the process<br />

of stepping through a program:<br />

To restart the program, select Restart from the Debug menu. The program is reloaded<br />

into memory, so any changes previously made to variables in the Watch window are<br />

undone. Also, you have to retype the name of your variable in the Memory window,<br />

because it resets itself to a default address.<br />

To stop debugging in the middle of a program, select Stop Debugging from the Debug<br />

menu.<br />

Note: Be sure to stop the debugger before trying to modify and re-assemble your program's<br />

source code. Otherwise, the linker will refuse to assemble your EXE file, indicating that it's<br />

currently in use.<br />

Page 14 of 14

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!