Volume 1 Application Programming (794095), страница 18
Текст из файла (страница 18)
The source and destination cannot both be memory locations. An immediateconstant can be used as a source operand with the MOV instruction. For MOV, the destination must beof the same size as the source, but the MOVSX and MOVZX instructions copy values of smaller size toa larger size by using sign-extension or zero-extension. The MOVD instruction copies a doubleword orquadword between a general-purpose register or memory and an XMM or MMX register.The MOV instruction is in many aspects similar to the assignment operator in high-level languages.The simplest example of their use is to initialize variables.
To initialize a register to 0, rather than usinga MOV instruction it may be more efficient to use the XOR instruction with identical destination andsource operands.The MOVNTI instruction stores a doubleword or quadword from a register into memory as “nontemporal” data, which assumes a single access (as opposed to frequent subsequent accesses of“temporal data”). The operation therefore minimizes cache pollution. The exact method by whichcache pollution is minimized depends on the hardware implementation of the instruction. For furtherinformation, see Section 3.9, “Memory Optimization,” on page 92.Conditional Move• CMOVcc—Conditional Move If conditionThe CMOVcc instructions conditionally copy a word, doubleword, or quadword from a register ormemory location to a register location. The source and destination must be of the same size.42General-Purpose Programming24592—Rev. 3.13—July 2007AMD64 TechnologyThe CMOVcc instructions perform the same task as MOV but work conditionally, depending on thestate of status flags in the RFLAGS register.
If the condition is not satisfied, the instruction has noeffect and control is passed to the next instruction. The mnemonics of CMOVcc instructions indicatethe condition that must be satisfied. Several mnemonics are often used for one opcode to make themnemonics easier to remember. For example, CMOVE (conditional move if equal) and CMOVZ(conditional move if zero) are aliases and compile to the same opcode. Table 3-4 shows the RFLAGSvalues required for each CMOVcc instruction.In assembly languages, the conditional move instructions correspond to small conditional statementslike:IF a = b THEN x = yCMOVcc instructions can replace two instructions—a conditional jump and a move. For example, toperform a high-level statement like:IF ECX = 5 THEN EAX = EBXwithout a CMOVcc instruction, the code would look like:cmp ecx, 5jnz Continuemov eax, ebxContinue:;;;;test if ecx equals 5test condition and skip if not metmovecontinuationbut with a CMOVcc instruction, the code would look like:cmp ecx, 5cmovz eax, ebx; test if ecx equals to 5; test condition and moveReplacing conditional jumps with conditional moves also has the advantage that it can avoid branchprediction penalties that may be caused by conditional jumps.Support for CMOVcc instructions depends on the processor implementation.
To find out if a processoris able to perform CMOVcc instructions, use the CPUID instruction.Table 3-4.MnemonicrFLAGS for CMOVcc InstructionsRequired Flag StateDescriptionCMOVOOF = 1Conditional move if overflowCMOVNOOF = 0Conditional move if not overflowCMOVBCMOVCCMOVNAECF = 1Conditional move if belowConditional move if carryConditional move if not above or equalCMOVAECMOVNBCMOVNCCF = 0Conditional move if above or equalConditional move if not belowConditional move if not carryCMOVECMOVZZF = 1Conditional move if equalConditional move if zeroGeneral-Purpose Programming43AMD64 TechnologyTable 3-4.Mnemonic24592—Rev. 3.13—July 2007rFLAGS for CMOVcc Instructions (continued)Required Flag StateDescriptionCMOVNECMOVNZZF = 0Conditional move if not equalConditional move if not zeroCMOVBECMOVNACF = 1 or ZF = 1Conditional move if below or equalConditional move if not aboveCMOVACMOVNBECF = 0 and ZF = 0Conditional move if not below or equalConditional move if not below or equalCMOVSSF = 1Conditional move if signCMOVNSSF = 0Conditional move if not signCMOVPCMOVPEPF = 1Conditional move if parityConditional move if parity evenCMOVNPCMOVPOPF = 0Conditional move if not parityConditional move if parity oddCMOVLCMOVNGESF <> OFConditional move if lessConditional move if not greater or equalCMOVGECMOVNLSF = OFConditional move if greater or equalConditional move if not lessCMOVLECMOVNGZF = 1 or SF <> OFConditional move if less or equalConditional move if not greaterCMOVGCMOVNLEZF = 0 and SF = OFConditional move if greaterConditional move if not less or equalStack Operations• POP—Pop Stack• POPA—Pop All to GPR Words• POPAD—Pop All to GPR Doublewords• PUSH—Push onto Stack• PUSHA—Push All GPR Words onto Stack• PUSHAD—Push All GPR Doublewords onto Stack• ENTER—Create Procedure Stack Frame• LEAVE—Delete Procedure Stack FramePUSH copies the specified register, memory location, or immediate value to the top of stack.
Thisinstruction decrements the stack pointer by 2, 4, or 8, depending on the operand size, and then copiesthe operand into the memory location pointed to by SS:rSP.POP copies a word, doubleword, or quadword from the memory location pointed to by the SS:rSPregisters (the top of stack) to a specified register or memory location. Then, the rSP register isincremented by 2, 4, or 8. After the POP operation, rSP points to the new top of stack.44General-Purpose Programming24592—Rev. 3.13—July 2007AMD64 TechnologyPUSHA or PUSHAD stores eight word-sized or doubleword-sized registers onto the stack: eAX, eCX,eDX, eBX, eSP, eBP, eSI and eDI, in that order. The stored value of eSP is sampled at the momentwhen the PUSHA instruction started.
The resulting stack-pointer value is decremented by 16 or 32.POPA or POPAD extracts eight word-sized or doubleword-sized registers from the stack: eDI, eSI,eBP, eSP, eBX, eDX, eCX and eAX, in that order (which is the reverse of the order used in the PUSHAinstruction). The stored eSP value is ignored by the POPA instruction. The resulting stack pointervalue is incremented by 16 or 32.It is a common practice to use PUSH instructions to pass parameters (via the stack) to functions andsubroutines. The typical instruction sequence used at the beginning of a subroutine looks like:pushmovsubebpebp, espesp, N; save current EBP; set stack frame pointer value; allocate space for local variablesThe rBP register is used as a stack frame pointer—a base address of the stack area used for parameterspassed to subroutines and local variables.
Positive offsets of the stack frame pointed to by rBP provideaccess to parameters passed while negative offsets give access to local variables. This technique allowscreating re-entrant subroutines.The ENTER and LEAVE instructions provide support for procedure calls, and are mainly used in highlevel languages. The ENTER instruction is typically the first instruction of the procedure, and theLEAVE instruction is the last before the RET instruction.The ENTER instruction creates a stack frame for a procedure. The first operand, size, specifies thenumber of bytes allocated in the stack. The second operand, depth, specifies the number of stack-framepointers copied from the calling procedure’s stack (i.e., the nesting level). The depth should be aninteger in the range 0–31.Typically, when a procedure is called, the stack contains the following four components:••••Parameters passed to the called procedure (created by the calling procedure).Return address (created by the CALL instruction).Array of stack-frame pointers (pointers to stack frames of procedures with smaller nesting-leveldepth) which are used to access the local variables of such procedures.Local variables used by the called procedure.All these data are called the stack frame.
The ENTER instruction simplifies management of the lasttwo components of a stack frame. First, the current value of the rBP register is pushed onto the stack.The value of the rSP register at that moment is a frame pointer for the current procedure: positiveoffsets from this pointer give access to the parameters passed to the procedure, and negative offsetsgive access to the local variables which will be allocated later. During procedure execution, the valueof the frame pointer is stored in the rBP register, which at that moment contains a frame pointer of thecalling procedure.