• Aucun résultat trouvé

■ The Right to Assemble 149 If you recall from the overview earlier in this chapter, debuggers need to be

Dans le document Assembly Language Step-by-Step (Page 185-189)

Taking a Trip Down Assembly Lane

Chapter 5 ■ The Right to Assemble 149 If you recall from the overview earlier in this chapter, debuggers need to be

told where to stop initially, before you can tell them to begin single-stepping a program—otherwise, they will scoot through execution of the whole program too quickly for you to follow. You have to set an initial breakpoint. The way to do this is to scroll the source code display down until you can see the code that follows the label_start:at the left edge of the program text. Move down two lines and left-click in the empty space at the left edge of the source code pane, between the window’s frame and the plus symbol. A red dot should appear where you clicked. This red dot indicates that you have now set a breakpoint on that line of code, which in this case is the instructionMOV EAX,4. (Make sure you insert a breakpoint at this instruction, and not at theNOPinstruction immediately above it in the program!)

Once you have the initial breakpoint set, click the Run button in the top toolbar. The button looks like a page with a downward-pointing arrow to its left. (Hover the mouse pointer over the button and it should say Run.) Two things will happen, essentially instantaneously (see Figure 5-14):

The red dot indicating the breakpoint will be overlain by a green triangle pointing to the right. The triangle indicates the place in the program where execution has paused, and it points at the next instruction that will execute. Note well that the instruction where execution pauses for a breakpointhas not been executed yet.

The top pane, which was blank previously, is now filled with a listing of the CPU registers. It’s a longish list because it includes all the CPU flags and floating-point processor registers, but you only need to see the top group for this demo.

At this point, the general-purpose registers will all be shown containing zeroes. Your program has begun running, but the only instruction that has run yet is theNOPinstruction, which does. . . nothing. (It’s a placeholder, and why it’s here in this program will have to wait until the next chapter.)

This will soon change. To do the first single-step, click the Step Into By Instruction button. Hover the mouse pointer over the buttons until you find it.

(The button has the focus in Figure 5-14.) As the name of the button suggests, clicking the button triggers the execution of one machine instruction. The green triangle moves one line downward.

Up in the Registers window, things are not the same. Two lines have turned red. The red color indicates that the values shown have changed during the execution of the single step that we just took. The EIP register is the instruction

150 Chapter 5 The Right to Assemble

pointer, and it keeps track of which instruction will be executed next. More interesting right now is the state of the EAX register. What had been 0x0 is now 0x4. If you look at the source code, the instruction we just executed was this:

mov eax,4

Figure 5-14: KDbg, ready to single-step

The ‘‘MOV’’ mnemonic tells us that data is being moved. The left operand is the destination (where data is going) and the right operand is the source (where data is coming from.) What happened is that the instruction put the value 4 in register EAX.

Click the Step Into By Instruction button again. The pointer will again move down a line. And again, the red lines in the Registers window indicate what was changed by executing the instruction. The instruction pointer changed

Chapter 5 The Right to Assemble 151 again; that shouldn’t be a surprise. Every time we execute an instruction, EIP will be red. This time, EAX has turned black again and EBX has turned red. The value in EBX has changed from 0 to 1. (The notation ‘‘0x1’’ is just another way of telling us that the value is given in hexadecimal.) Clearly, we’ve moved the value 1 into register EBX; and that’s the instruction we just executed:

mov ebx,1

Click the button again. This time, register ECX will change radically (see Figure 5-15). The precise number you see on your PC for ECX will differ from the precise number I saw when I took the screen shot. The value depends on the individual Linux system, how much memory you have, and what the Linux OS is doing elsewhere in memory. What matters is that a 32-bit hexadecimal value has been moved into ECX. This instruction did the work:

mov ecx,EatMsg

So what did we actually move? If you scroll up into the earlier part of the source code temporarily, you’ll see thatEatMsgis a quoted string of ordinary characters reading ‘‘Eat at Joe’s!’’ and not a 32-bit number; but note the comment to the right of the instruction: ‘‘Pass offset of the message.’’ What we actually loaded into ECX was not the message itself but the message’s address in memory. Technically, in IA-32 protected mode, a data item like EatMsg has both a segment address and an offset address. The segment address, however, is the property of the operating system, and we can safely ignore it when doing this kind of simple user-space programming. Back in the DOS era, when we had to use the real mode segmented memory model, we had to keep track of the segment registers too; doing it the protected mode way means one less headache. (Don’t worry; there are plenty more!)

Click Step Into By Instruction again, and register EDX will be given the value 0xe, or (in decimal) 14. This is the length of the character stringEatMsg.

At this point all the setup work has been done with respect to moving various values where they need to go. Click the button and execute the next instruction:

int 80H

It looks like nothing has happened—nothing in the Registers window changed—but hold on. Go into KDbg’s menus and select View→Output. A simple terminal window will appear—and there’s EatMsg, telling the world where to go for lunch (see Figure 5-16).

152 Chapter 5 The Right to Assemble

Figure 5-15: Moving a memory address into a register

Figure 5-16: Program output in a terminal window

The INT 80Hinstruction is a special one. It generates a Linux system call (affectionately referred to as asyscall) namedsys_write, which sends data to the currently active terminal window.

SendingEatMsgto the output window is all that the eatsyscall program was designed to do. Its work is done, and the last three instructions in the program

Chapter 5 The Right to Assemble 153 basically tidy up and leave. Click the button and step through them, watching to see that EAX and EBX receive new values before the finalINT 80H, which signals Linux that this program is finished. You’ll get a confirmation of that in the bottom line of KDbg’s window, which will say ‘‘Program exited normally’’

along with the source code line where this exit happened.

One question that may have occurred to you is this: Why is the stepper button called ‘‘StepIntoBy Instruction’’? We just bounced down to the next line; we did not step our wayintoanything. A full answer will have to wait for a couple of chapters, until we get into procedures, but the gist of it is this: KDbg gives you the option to trace execution step by step into an assembly language procedure, or to let the computer run full speed while executing the procedure.

The button Step Into By Instruction specifies to go through a procedure step by step. The button Step Over By Instruction (the next button to the right) allows the procedure to execute at full speed, and pick up single-stepping on the other side of the procedure call.

Why step over a procedure call? Mainly this: procedures are often library procedures, which you or someone else may have written months or years ago. If they are already debugged and working, stepping through them is probably a waste of time. (You can, however, learn a great deal about how the procedure works by watching it run one instruction at a time.)

Conversely, if the procedures are new to the program at hand, you may need to step through them just as carefully as you step through the main part of the program. KDbg gives you the option. This simple program has no procedures, so the Step Into and Step Over buttons do precisely the same thing: execute the next instruction in sequence.

The three single-stepping buttons to the left of Step Into By Instruction are for use when debugging code in higher-level languages such as C. They enable stepping by one high-levelstatementat a time, not simply one machine instruc-tion at a time. These buttons don’t apply to assembly language programming and I won’t be discussing them further.

Dans le document Assembly Language Step-by-Step (Page 185-189)