banner



How Many Bytes Are Required To Fill A 32-bit Register?

x86 Assembly Guide

Contents: Registers | Memory and Addressing | Instructions | Calling Convention

This guide describes the nuts of 32-bit x86 assembly language programming, covering a pocket-size only useful subset of the bachelor instructions and assembler directives. In that location are several different assembly languages for generating x86 machine code. The ane nosotros volition use in CS216 is the Microsoft Macro Assembler (MASM) assembler. MASM uses the standard Intel syntax for writing x86 assembly code.

The full x86 instruction fix is big and circuitous (Intel's x86 instruction set manuals comprise over 2900 pages), and we do non cover information technology all in this guide. For example, at that place is a 16-fleck subset of the x86 instruction ready. Using the 16-bit programming model tin can be quite complex. It has a segmented retention model, more than restrictions on register usage, and so on. In this guide, we volition limit our attention to more modern aspects of x86 programming, and delve into the didactics gear up only in enough detail to get a basic feel for x86 programming.

Resources

  • Guide to Using Assembly in Visual Studio — a tutorial on edifice and debugging assembly code in Visual Studio
  • Intel x86 Instruction Set up Reference
  • Intel'due south Pentium Manuals (the full gory details)

Registers

Mod (i.due east 386 and beyond) x86 processors have eight 32-bit general purpose registers, as depicted in Effigy i. The register names are mostly historical. For instance, EAX used to exist called the accumulator since information technology was used by a number of arithmetic operations, and ECX was known equally the counter since information technology was used to agree a loop index. Whereas virtually of the registers have lost their special purposes in the modernistic educational activity set, by convention, two are reserved for special purposes — the stack arrow (ESP) and the base pointer (EBP).

For the EAX, EBX, ECX, and EDX registers, subsections may be used. For instance, the to the lowest degree meaning 2 bytes of EAX can exist treated as a sixteen-bit register called AX. The least significant byte of AX tin can be used every bit a single eight-bit annals called AL, while the nigh significant byte of AX tin can be used every bit a single eight-scrap register called AH. These names refer to the same physical register. When a two-byte quantity is placed into DX, the update affects the value of DH, DL, and EDX. These sub-registers are mainly hold-overs from older, 16-flake versions of the instruction set. However, they are sometimes convenient when dealing with data that are smaller than 32-$.25 (e.g. ane-byte ASCII characters).

When referring to registers in assembly language, the names are not case-sensitive. For case, the names EAX and eax refer to the same register.


Figure ane. x86 Registers

Retention and Addressing Modes

Declaring Static Information Regions

You can declare static data regions (coordinating to global variables) in x86 assembly using special assembler directives for this purpose. Information declarations should be preceded by the .DATA directive. Post-obit this directive, the directives DB, DW, and DD tin can be used to declare i, two, and iv byte data locations, respectively. Alleged locations can exist labeled with names for later reference — this is similar to declaring variables by name, simply abides by some lower level rules. For example, locations declared in sequence will be located in memory next to one another.

Example declarations:

.Data
var DB 64 ; Declare a byte, referred to as location var, containing the value 64.
var2 DB ? ; Declare an uninitialized byte, referred to equally location var2.
DB ten ; Declare a byte with no characterization, containing the value ten. Its location is var2 + 1.
Ten DW ? ; Declare a 2-byte uninitialized value, referred to every bit location X.
Y DD 30000 ; Declare a iv-byte value, referred to as location Y, initialized to 30000.

Unlike in high level languages where arrays tin can have many dimensions and are accessed past indices, arrays in x86 assembly language are merely a number of cells located contiguously in retentivity. An array tin can exist declared by simply listing the values, as in the first example below. Two other mutual methods used for declaring arrays of data are the DUP directive and the use of string literals. The DUP directive tells the assembler to duplicate an expression a given number of times. For example, iv DUP(two) is equivalent to 2, 2, two, ii.

Some examples:

Z DD ane, two, iii ; Declare three 4-byte values, initialized to 1, 2, and three. The value of location Z + 8 volition be 3.
bytes DB 10 DUP(?) ; Declare x uninitialized bytes starting at location bytes.
arr DD 100 DUP(0) ; Declare 100 4-byte words starting at location arr, all initialized to 0
str DB 'hello',0 ; Declare 6 bytes starting at the address str, initialized to the ASCII graphic symbol values for howdy and the null (0) byte.

Addressing Memory

Modern x86-compatible processors are capable of addressing upwards to ii32 bytes of retentivity: memory addresses are 32-bits wide. In the examples above, where we used labels to refer to memory regions, these labels are actually replaced by the assembler with 32-fleck quantities that specify addresses in memory. In addition to supporting referring to memory regions by labels (i.due east. abiding values), the x86 provides a flexible scheme for computing and referring to memory addresses: up to two of the 32-bit registers and a 32-chip signed constant can be added together to compute a retentiveness accost. One of the registers tin be optionally pre-multiplied past two, four, or viii.

The addressing modes can exist used with many x86 instructions (nosotros'll describe them in the side by side department). Hither we illustrate some examples using the mov educational activity that moves data betwixt registers and memory. This instruction has two operands: the first is the destination and the 2d specifies the source.

Some examples of mov instructions using address computations are:

mov eax, [ebx] ; Move the 4 bytes in memory at the address contained in EBX into EAX
mov [var], ebx ; Motion the contents of EBX into the 4 bytes at retentiveness address var. (Notation, var is a 32-bit constant).
mov eax, [esi-4] ; Movement iv bytes at memory address ESI + (-four) into EAX
mov [esi+eax], cl ; Move the contents of CL into the byte at address ESI+EAX
mov edx, [esi+4*ebx] ; Move the four bytes of data at address ESI+iv*EBX into EDX

Some examples of invalid address calculations include:

mov eax, [ebx-ecx] ; Tin but add annals values
mov [eax+esi+edi], ebx ; At well-nigh ii registers in address computation

Size Directives

In full general, the intended size of the information item at a given memory address tin be inferred from the assembly code instruction in which it is referenced. For instance, in all of the above instructions, the size of the memory regions could be inferred from the size of the register operand. When we were loading a 32-bit annals, the assembler could infer that the region of memory we were referring to was four bytes wide. When we were storing the value of a ane byte annals to retentivity, the assembler could infer that nosotros wanted the address to refer to a single byte in retentiveness.

All the same, in some cases the size of a referred-to memory region is cryptic. Consider the instruction mov [ebx], ii. Should this education motility the value ii into the single byte at address EBX? Perhaps it should move the 32-scrap integer representation of 2 into the 4-bytes starting at accost EBX. Since either is a valid possible interpretation, the assembler must exist explicitly directed as to which is correct. The size directives BYTE PTR, WORD PTR, and DWORD PTR serve this purpose, indicating sizes of 1, ii, and 4 bytes respectively.

For example:

mov BYTE PTR [ebx], 2 ; Move 2 into the unmarried byte at the accost stored in EBX.
mov WORD PTR [ebx], 2 ; Move the 16-chip integer representation of ii into the ii bytes starting at the accost in EBX.
mov DWORD PTR [ebx], 2 ; Move the 32-bit integer representation of 2 into the 4 bytes starting at the address in EBX.

Instructions

Machine instructions generally fall into three categories: information move, arithmetic/logic, and control-menses. In this section, nosotros will wait at of import examples of x86 instructions from each category. This section should not be considered an exhaustive list of x86 instructions, merely rather a useful subset. For a consummate listing, see Intel's pedagogy set reference.

We utilise the post-obit notation:

<reg32> Whatever 32-bit annals (EAX, EBX, ECX, EDX, ESI, EDI, ESP, or EBP)
<reg16> Whatsoever xvi-bit register (AX, BX, CX, or DX)
<reg8> Whatsoever 8-bit register (AH, BH, CH, DH, AL, BL, CL, or DL)
<reg> Any annals
<mem> A retentivity accost (e.g., [eax], [var + 4], or dword ptr [eax+ebx])
<con32> Any 32-bit abiding
<con16> Whatever 16-bit constant
<con8> Any 8-bit constant
<con> Any 8-, 16-, or 32-bit constant

Data Movement Instructions

mov — Move (Opcodes: 88, 89, 8A, 8B, 8C, 8E, ...)

The mov instruction copies the data detail referred to by its second operand (i.e. register contents, memory contents, or a abiding value) into the location referred to by its first operand (i.eastward. a register or memory). While register-to-annals moves are possible, direct retentivity-to-retention moves are not. In cases where retention transfers are desired, the source memory contents must outset be loaded into a register, then can be stored to the destination retentiveness accost.

Syntax
mov <reg>,<reg>
mov <reg>,<mem>
mov <mem>,<reg>
mov <reg>,<const>
mov <mem>,<const>

Examples
mov eax, ebx — copy the value in ebx into eax
mov byte ptr [var], five — shop the value v into the byte at location var

push — Push stack (Opcodes: FF, 89, 8A, 8B, 8C, 8E, ...)

The push teaching places its operand onto the meridian of the hardware supported stack in memory. Specifically, button showtime decrements ESP past 4, then places its operand into the contents of the 32-bit location at address [ESP]. ESP (the stack pointer) is decremented by push since the x86 stack grows downwardly - i.e. the stack grows from high addresses to lower addresses. Syntax
push <reg32>
push <mem>
push <con32>

Examples
push eax — push eax on the stack
push button [var] — push button the 4 bytes at address var onto the stack

pop — Popular stack

The pop instruction removes the 4-byte data element from the top of the hardware-supported stack into the specified operand (i.e. annals or memory location). Information technology first moves the 4 bytes located at memory location [SP] into the specified register or memory location, and and then increments SP by four.

Syntax
pop <reg32>
pop <mem>

Examples
pop edi — pop the top element of the stack into EDI.
pop [ebx] — popular the top element of the stack into memory at the four bytes starting at location EBX.

lea — Load effective accost

The lea instruction places the address specified by its 2nd operand into the register specified by its start operand. Note, the contents of the memory location are non loaded, simply the effective address is computed and placed into the register. This is useful for obtaining a pointer into a memory region.

Syntax
lea <reg32>,<mem>

Examples
lea edi, [ebx+4*esi] — the quantity EBX+4*ESI is placed in EDI.
lea eax, [var] — the value in var is placed in EAX.
lea eax, [val] — the value val is placed in EAX.

Arithmetics and Logic Instructions

add together — Integer Addition

The add instruction adds together its two operands, storing the result in its first operand. Annotation, whereas both operands may be registers, at most ane operand may be a memory location. Syntax
add <reg>,<reg>
add together <reg>,<mem>
add <mem>,<reg>
add together <reg>,<con>
add <mem>,<con>
Examples
add eax, 10 — EAX ← EAX + 10
add BYTE PTR [var], ten — add together 10 to the single byte stored at retentiveness accost var

sub — Integer Subtraction

The sub didactics stores in the value of its offset operand the result of subtracting the value of its 2nd operand from the value of its starting time operand. As with add together Syntax
sub <reg>,<reg>
sub <reg>,<mem>
sub <mem>,<reg>
sub <reg>,<con>
sub <mem>,<con>
Examples
sub al, ah — AL ← AL - AH
sub eax, 216 — subtract 216 from the value stored in EAX

inc, dec — Increase, Decrement

The inc pedagogy increments the contents of its operand by one. The dec instruction decrements the contents of its operand by one.

Syntax
inc <reg>
inc <mem>
december <reg>
december <mem>

Examples
dec eax — subtract i from the contents of EAX.
inc DWORD PTR [var] — add i to the 32-fleck integer stored at location var

imul — Integer Multiplication

The imul instruction has two basic formats: two-operand (first two syntax listings higher up) and three-operand (last ii syntax listings above). The two-operand course multiplies its two operands together and stores the result in the first operand. The result (i.east. showtime) operand must be a annals. The three operand form multiplies its 2nd and third operands together and stores the result in its beginning operand. Again, the result operand must be a register. Furthermore, the tertiary operand is restricted to being a abiding value. Syntax
imul <reg32>,<reg32>
imul <reg32>,<mem>
imul <reg32>,<reg32>,<con>
imul <reg32>,<mem>,<con>

Examples

imul eax, [var] — multiply the contents of EAX past the 32-scrap contents of the memory location var. Shop the result in EAX.

imul esi, edi, 25 — ESI → EDI * 25

idiv — Integer Division

The idiv educational activity divides the contents of the 64 bit integer EDX:EAX (constructed past viewing EDX equally the most significant four bytes and EAX as the least significant iv bytes) past the specified operand value. The quotient upshot of the division is stored into EAX, while the remainder is placed in EDX.

Syntax
idiv <reg32>
idiv <mem>

Examples

idiv ebx — divide the contents of EDX:EAX by the contents of EBX. Place the quotient in EAX and the remainder in EDX.

idiv DWORD PTR [var] — divide the contents of EDX:EAX by the 32-bit value stored at memory location var. Place the caliber in EAX and the residue in EDX.

and, or, xor — Bitwise logical and, or and sectional or

These instructions perform the specified logical operation (logical bitwise and, or, and exclusive or, respectively) on their operands, placing the result in the kickoff operand location.

Syntax
and <reg>,<reg>
and <reg>,<mem>
and <mem>,<reg>
and <reg>,<con>
and <mem>,<con>

or <reg>,<reg>
or <reg>,<mem>
or <mem>,<reg>
or <reg>,<con>
or <mem>,<con>

xor <reg>,<reg>
xor <reg>,<mem>
xor <mem>,<reg>
xor <reg>,<con>
xor <mem>,<con>

Examples
and eax, 0fH — articulate all but the concluding 4 bits of EAX.
xor edx, edx — fix the contents of EDX to zero.

non — Bitwise Logical Non

Logically negates the operand contents (that is, flips all fleck values in the operand).

Syntax
not <reg>
non <mem>

Example
non BYTE PTR [var] — negate all bits in the byte at the memory location var.

neg — Negate

Performs the two's complement negation of the operand contents.

Syntax
neg <reg>
neg <mem>

Case
neg eax — EAX → - EAX

shl, shr — Shift Left, Shift Right

These instructions shift the bits in their first operand's contents left and right, padding the resulting empty bit positions with zeros. The shifted operand can be shifted up to 31 places. The number of bits to shift is specified past the second operand, which can be either an 8-bit constant or the register CL. In either case, shifts counts of greater then 31 are performed modulo 32.

Syntax
shl <reg>,<con8>
shl <mem>,<con8>
shl <reg>,<cl>
shl <mem>,<cl>

shr <reg>,<con8>
shr <mem>,<con8>
shr <reg>,<cl>
shr <mem>,<cl>

Examples

shl eax, 1 — Multiply the value of EAX past 2 (if the most meaning chip is 0)

shr ebx, cl — Store in EBX the floor of result of dividing the value of EBX past two n wheren is the value in CL.

Control Flow Instructions

The x86 processor maintains an instruction arrow (IP) register that is a 32-bit value indicating the location in memory where the current instruction starts. Commonly, it increments to point to the adjacent instruction in memory begins afterward execution an didactics. The IP register cannot exist manipulated straight, but is updated implicitly past provided command period instructions.

Nosotros employ the note <characterization> to refer to labeled locations in the program text. Labels can be inserted anywhere in x86 assembly code text by inbound a characterization name followed by a colon. For example,

            mov esi, [ebp+viii] begin: xor ecx, ecx        mov eax, [esi]          

The second instruction in this code fragment is labeled begin. Elsewhere in the code, we tin refer to the memory location that this instruction is located at in memory using the more convenient symbolic name begin. This label is just a user-friendly mode of expressing the location instead of its 32-chip value.

jmp — Jump

Transfers program control menses to the instruction at the memory location indicated by the operand.

Syntax
jmp <label>

Example
jmp brainstorm — Bound to the instruction labeled brainstorm.

jcondition — Conditional Jump

These instructions are conditional jumps that are based on the condition of a set of condition codes that are stored in a special annals chosen the machine condition word. The contents of the machine status word include information about the last arithmetic performance performed. For example, one flake of this discussion indicates if the terminal outcome was goose egg. Another indicates if the last result was negative. Based on these condition codes, a number of provisional jumps can be performed. For example, the jz instruction performs a bound to the specified operand label if the outcome of the last arithmetics operation was nothing. Otherwise, control proceeds to the next educational activity in sequence.

A number of the provisional branches are given names that are intuitively based on the last operation performed being a special compare instruction, cmp (see below). For example, conditional branches such as jle and jne are based on first performing a cmp operation on the desired operands.

Syntax
je <label> (jump when equal)
jne <characterization> (jump when not equal)
jz <label> (jump when last result was zilch)
jg <characterization> (jump when greater than)
jge <characterization> (bound when greater than or equal to)
jl <label> (jump when less than)
jle <label> (jump when less than or equal to)

Instance
cmp eax, ebx
jle done

If the contents of EAX are less than or equal to the contents of EBX, bound to the label done. Otherwise, continue to the side by side instruction.

cmp — Compare

Compare the values of the ii specified operands, setting the condition codes in the motorcar status word accordingly. This instruction is equivalent to the sub pedagogy, except the event of the subtraction is discarded instead of replacing the offset operand.

Syntax
cmp <reg>,<reg>
cmp <reg>,<mem>
cmp <mem>,<reg>
cmp <reg>,<con>

Example
cmp DWORD PTR [var], x
jeq loop

If the 4 bytes stored at location var are equal to the 4-byte integer constant 10, jump to the location labeled loop.

call, ret — Subroutine call and return

These instructions implement a subroutine telephone call and return. The call education start pushes the electric current code location onto the hardware supported stack in memory (see the push button instruction for details), so performs an unconditional bound to the code location indicated by the label operand. Unlike the unproblematic jump instructions, the call educational activity saves the location to return to when the subroutine completes.

The ret instruction implements a subroutine return machinery. This instruction first pops a code location off the hardware supported in-retentiveness stack (see the pop instruction for details). Information technology then performs an unconditional leap to the retrieved lawmaking location.

Syntax
call <label>
ret

Calling Convention

To allow split programmers to share code and develop libraries for use by many programs, and to simplify the employ of subroutines in full general, programmers typically adopt a common calling convention. The calling convention is a protocol about how to call and return from routines. For example, given a fix of calling convention rules, a programmer need non examine the definition of a subroutine to determine how parameters should be passed to that subroutine. Furthermore, given a set of calling convention rules, high-level language compilers can be made to follow the rules, thus allowing hand-coded assembly language routines and high-level linguistic communication routines to call i another.

In practice, many calling conventions are possible. Nosotros volition use the widely used C language calling convention. Following this convention will permit you lot to write assembly language subroutines that are safely callable from C (and C++) code, and will also enable you to call C library functions from your associates language code.

The C calling convention is based heavily on the use of the hardware-supported stack. It is based on the button, pop, phone call, and ret instructions. Subroutine parameters are passed on the stack. Registers are saved on the stack, and local variables used by subroutines are placed in retentivity on the stack. The vast bulk of high-level procedural languages implemented on well-nigh processors take used similar calling conventions.

The calling convention is broken into two sets of rules. The kickoff set of rules is employed past the caller of the subroutine, and the second set of rules is observed past the author of the subroutine (the callee). It should be emphasized that mistakes in the observance of these rules quickly effect in fatal plan errors since the stack will be left in an inconsistent country; thus meticulous care should be used when implementing the call convention in your own subroutines.

>
Stack during Subroutine Phone call
[Thanks to Maxence Faldor for providing a correct figure and to James Peterson for finding and fixing the bug in the original version of this figure!]

A good way to visualize the operation of the calling convention is to draw the contents of the nearby region of the stack during subroutine execution. The image in a higher place depicts the contents of the stack during the execution of a subroutine with three parameters and three local variables. The cells depicted in the stack are 32-flake wide retention locations, thus the memory addresses of the cells are 4 bytes apart. The first parameter resides at an offset of 8 bytes from the base arrow. Above the parameters on the stack (and below the base pointer), the telephone call instruction placed the return address, thus leading to an actress four bytes of offset from the base arrow to the starting time parameter. When the ret instruction is used to render from the subroutine, it will leap to the return accost stored on the stack.

Caller Rules

To make a subrouting phone call, the caller should:

  1. Before calling a subroutine, the caller should salvage the contents of certain registers that are designated caller-saved. The caller-saved registers are EAX, ECX, EDX. Since the called subroutine is immune to modify these registers, if the caller relies on their values after the subroutine returns, the caller must push the values in these registers onto the stack (so they tin be restore later the subroutine returns.
  2. To pass parameters to the subroutine, push button them onto the stack before the phone call. The parameters should exist pushed in inverted order (i.eastward. final parameter first). Since the stack grows downwards, the first parameter will be stored at the lowest address (this inversion of parameters was historically used to permit functions to be passed a variable number of parameters).
  3. To phone call the subroutine, utilise the call pedagogy. This instruction places the return address on top of the parameters on the stack, and branches to the subroutine lawmaking. This invokes the subroutine, which should follow the callee rules beneath.

After the subroutine returns (immediately following the call instruction), the caller can expect to find the return value of the subroutine in the register EAX. To restore the machine state, the caller should:

  1. Remove the parameters from stack. This restores the stack to its state before the phone call was performed.
  2. Restore the contents of caller-saved registers (EAX, ECX, EDX) by popping them off of the stack. The caller tin can assume that no other registers were modified by the subroutine.

Example
The code below shows a office telephone call that follows the caller rules. The caller is calling a function _myFunc that takes three integer parameters. Kickoff parameter is in EAX, the second parameter is the constant 216; the tertiary parameter is in memory location var.

push [var] ; Push last parameter starting time push 216   ; Push the second parameter button eax   ; Push button first parameter last  call _myFunc ; Call the role (assume C naming)  add together esp, 12          

Notation that after the call returns, the caller cleans up the stack using the add instruction. We have 12 bytes (iii parameters * 4 bytes each) on the stack, and the stack grows down. Thus, to go rid of the parameters, we tin can simply add 12 to the stack pointer.

The upshot produced by _myFunc is now bachelor for use in the register EAX. The values of the caller-saved registers (ECX and EDX), may accept been inverse. If the caller uses them after the telephone call, it would take needed to salve them on the stack before the call and restore them after it.

Callee Rules

The definition of the subroutine should adhere to the following rules at the beginning of the subroutine:

  1. Push button the value of EBP onto the stack, and and then copy the value of ESP into EBP using the following instructions:
                  push ebp     mov  ebp, esp            
    This initial action maintains the base of operations pointer, EBP. The base pointer is used by convention as a point of reference for finding parameters and local variables on the stack. When a subroutine is executing, the base pointer holds a re-create of the stack pointer value from when the subroutine started executing. Parameters and local variables will always be located at known, abiding offsets away from the base pointer value. We push button the onetime base of operations arrow value at the beginning of the subroutine so that we can later on restore the appropriate base arrow value for the caller when the subroutine returns. Remember, the caller is not expecting the subroutine to alter the value of the base arrow. We then motion the stack pointer into EBP to obtain our point of reference for accessing parameters and local variables.
  2. Next, classify local variables by making infinite on the stack. Recall, the stack grows down, so to make space on the top of the stack, the stack arrow should be decremented. The amount past which the stack pointer is decremented depends on the number and size of local variables needed. For example, if 3 local integers (four bytes each) were required, the stack arrow would need to be decremented by 12 to make space for these local variables (i.e., sub esp, 12). Every bit with parameters, local variables will be located at known offsets from the base pointer.
  3. Next, save the values of the callee-saved registers that volition be used by the function. To salve registers, push them onto the stack. The callee-saved registers are EBX, EDI, and ESI (ESP and EBP will as well exist preserved past the calling convention, but need not be pushed on the stack during this step).

Afterwards these three actions are performed, the body of the subroutine may proceed. When the subroutine is returns, information technology must follow these steps:

  1. Exit the return value in EAX.
  2. Restore the old values of any callee-saved registers (EDI and ESI) that were modified. The register contents are restored by popping them from the stack. The registers should be popped in the changed order that they were pushed.
  3. Deallocate local variables. The obvious mode to do this might be to add together the appropriate value to the stack pointer (since the space was allocated past subtracting the needed amount from the stack pointer). In practice, a less error-prone way to deallocate the variables is to move the value in the base arrow into the stack pointer: mov esp, ebp. This works because the base of operations arrow ever contains the value that the stack pointer contained immediately prior to the resource allotment of the local variables.
  4. Immediately before returning, restore the caller's base arrow value past popping EBP off the stack. Retrieve that the outset thing we did on entry to the subroutine was to push the base pointer to save its old value.
  5. Finally, return to the caller by executing a ret pedagogy. This didactics volition find and remove the appropriate return address from the stack.

Note that the callee's rules fall cleanly into two halves that are basically mirror images of one some other. The first half of the rules use to the get-go of the office, and are commonly said to define the prologue to the function. The latter half of the rules utilize to the end of the function, and are thus usually said to define the epilogue of the function.

Example
Here is an example function definition that follows the callee rules:

.486 .MODEL Flat .Code PUBLIC _myFunc _myFunc PROC   ; Subroutine Prologue   push ebp     ; Save the old base pointer value.   mov ebp, esp ; Set the new base pointer value.   sub esp, 4   ; Make room for i iv-byte local variable.   push edi     ; Relieve the values of registers that the function   push esi     ; will change. This function uses EDI and ESI.   ; (no need to save EBX, EBP, or ESP)    ; Subroutine Body   mov eax, [ebp+eight]   ; Movement value of parameter 1 into EAX   mov esi, [ebp+12]  ; Move value of parameter 2 into ESI   mov edi, [ebp+xvi]  ; Move value of parameter 3 into EDI    mov [ebp-four], edi   ; Move EDI into the local variable   add [ebp-four], esi   ; Add ESI into the local variable   add eax, [ebp-4]   ; Add together the contents of the local variable                      ; into EAX (final result)    ; Subroutine Epilogue    pop esi      ; Recover register values   pop  edi   mov esp, ebp ; Deallocate local variables   pop ebp ; Restore the caller's base pointer value   ret _myFunc ENDP Terminate          

The subroutine prologue performs the standard actions of saving a snapshot of the stack pointer in EBP (the base of operations arrow), allocating local variables by decrementing the stack pointer, and saving register values on the stack.

In the body of the subroutine we tin can see the use of the base pointer. Both parameters and local variables are located at constant offsets from the base pointer for the elapsing of the subroutines execution. In item, we notice that since parameters were placed onto the stack before the subroutine was chosen, they are always located below the base of operations pointer (i.e. at higher addresses) on the stack. The starting time parameter to the subroutine tin can ever be establish at memory location EBP + 8, the second at EBP + 12, the third at EBP + sixteen. Similarly, since local variables are allocated after the base pointer is set up, they e'er reside in a higher place the base arrow (i.e. at lower addresses) on the stack. In item, the kickoff local variable is always located at EBP - iv, the 2d at EBP - viii, and then on. This conventional use of the base of operations pointer allows us to apace identify the use of local variables and parameters within a office body.

The function epilogue is basically a mirror image of the function prologue. The caller's register values are recovered from the stack, the local variables are deallocated by resetting the stack pointer, the caller's base arrow value is recovered, and the ret educational activity is used to return to the advisable code location in the caller.

Using these Materials

These materials are released under a Creative Commons Attribution-Noncommercial-Share Akin 3.0 United States License. We are delighted when people desire to use or suit the course materials we developed, and you are welcome to reuse and adapt these materials for any non-commercial purposes (if you would like to use them for a commercial purpose, please contact David Evans for more than information). If you do arrange or use these materials, delight include a credit like "Adapted from materials developed for University of Virginia cs216 by David Evans. This guide was revised for cs216 by David Evans, based on materials originally created by Adam Ferrari many years ago, and since updated by Alan Batson, Mike Lack, and Anita Jones." and a link back to this page.


How Many Bytes Are Required To Fill A 32-bit Register?,

Source: https://www.cs.virginia.edu/~evans/cs216/guides/x86.html

Posted by: hannayouteret.blogspot.com

0 Response to "How Many Bytes Are Required To Fill A 32-bit Register?"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel