程序的机器级表示(四)

Loops:

Instead, combinations of condi- tional tests and jumps are used to implement the effect of loops. Most compilers generate loop code based on the do-while form of a loop, even though this form is relatively uncommon in actual programs. Other loops are transformed into do- while form and then compiled into machine code. 

REVERSE ENGINEERING

SWITCH

Procedures :

A procedure call involves passing both data (in the form of procedure parame- ters and return values) and control from one part of a program to another. In addition, it must allocate space for the local variables of the procedure on entry and deallocate them on exit. Most machines, including IA32, provide only simple instructions for transferring control to and from procedures. The passing of data and the allocation and deallocation of local variables is handled by manipulating the program stack. 

Stack Frame Structure 

IA32 programs make use of the program stack to support procedure calls. The machine uses the stack to pass procedure arguments, to store return information,

to save registers for later restoration, and for local storage. The portion of the stack allocated for a single procedure call is called a stack frame.  

The topmost stack frame is delimited by two pointers, with register %ebp serving as the frame pointer, and register %esp serving as the stack pointer.

The stack pointer can move while the procedure is executing, and hence most information is accessed relative to the frame pointer. 

扫描二维码关注公众号,回复: 1572363 查看本文章

调用的准备工作:

Suppose procedure P (the caller) calls procedure Q (the callee). The arguments to Q are contained within the stack frame for P. In addition,

when P calls Q, the return address within P where the program should resume execution when it returns from Q is pushed onto the stack,

forming the end of P’s stack frame. The stack frame for Q starts with the saved value of the frame pointer (a copy of register %ebp),

followed by copies of any other saved register values. 

过程Q使用stack来存储局部变量(不存储在register中)的情形:

  • There are not enough registers to hold all of the local data.

  • Some of the local variables are arrays or structures and hence must be accessed

    by array or structure references.

  • The address operator ‘&’ is applied to a local variable, and hence we must be able to generate an address for it. 

 一点细节:
Space for data with no specified initial value can be allocated on the stack by simply decrementing the stack pointer by an appropriate amount.
Similarly, space can be deallocated by incrementing the stack pointer. 

Transferring Control:

The instructions supporting procedure calls and returns are shown in the following table: 

The call instruction has a target indicating the address of the instruction where the called procedure starts.

Like jumps, a call can either be direct or indirect. In assembly code, the target of a direct call is given as a label, while the target of an indirect call is

given by a * followed by an operand specifier using one of the formats described in Section 3.4.1. 

The effect of a call instruction is to push a return address on the stack and jump to the start of the called procedure.

The return address is the address of the instruction immediately following the call in the program, so that execution will resume at this location

when the called procedure returns. The ret instruction pops an address off the stack and jumps to this location. 

一段在main中调用sum的汇编代码:

对应的图示:

对这个过程的解读:

In this code, we can see that the call instruction with address 0x080483dc in main calls function sum.

This status is shown in Figure 3.22(a), with the indicated values for the stack pointer %esp and the program counter %eip.

The effect of the call is to push the return address 0x080483e1 onto the stack and to jump to the first instruction in function sum,

at address 0x08048394 (Figure 3.22(b)).

The execution of function sum continues until it hits the ret instruction at address 0x080483a4. This instruction pops the value 0x080483e1 from the

stack and jumps to this address, resuming the execution of main just after the call instruction in sum (Figure 3.22(c)). 

一道练习:

    call next
next:
    popl %eax

A. %eax is set to the address of the popl instruction.

B. This is not a true procedure call, since the control follows the same ordering as the instructions and the return address is popped from the stack.

C. This is the only way in IA32 to get the value of the program counter into an integer register.

Register Usage Conventions 

Why the conventions are needed:

The set of program registers acts as a single resource shared by all of the proce- dures. Although only one procedure can be active at a given time,

we must make sure that when one procedure (the caller) calls another (the callee), the callee does not overwrite some register value that the

caller planned to use later. For this reason, IA32 adopts a uniform set of conventions for register usage that must be respected by all procedures,

including those in program libraries. 

caller-save registers and callee-save registers:

By convention, registers %eax, %edx, and %ecx are classified as caller-save registers.

When procedure Q is called by P, it can overwrite these registers without destroying any data required by P.

On the other hand, registers %ebx, %esi, and %edi are classified as callee-save registers.

This means that Q must save the values of any of these registers on the stack before overwriting them, and restore(恢复) them before returning,

because P (or some higher-level procedure) may need these values for its future computations. In addition,

registers %ebp and %esp must be maintained according to the conventions described here. 

猜你喜欢

转载自www.cnblogs.com/geeklove01/p/9166582.html
今日推荐