- 论坛徽章:
- 0
|
The MOV instruction formats
The basic format of the MOV instruction is as follows:
movx source, destination
The source and destination values can be memory addresses, data values stored in memory, data values defined in the instruction statement, or registers.
The GNU assembler adds another dimension to the MOV instruction, in that the size of the data element moved must be declared. The size is declared by adding an additional character to the MOV mnemonic:
movx
where x can be the following:
- l for a 32-bit long word value
- w for a 16-bit word value
- b for an 8-bit byte value
Using indexed memory locations
You can specify more than one value on a directive to place in memory:
values:.int 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60
The way this is done is called indexed memory mode. The memory location is determined by the following:
- A base address
- An offset address to add to the base address
- The size of the data element
- An index to determine which data element to select
The format of the expression is
base_address(offset_address, index, size)
The data value retrieved is located at
base_address + offset_address + index * size
If any of the values are zero, they can be omitted (but the commas are still required as placeholders). The offset_address and index value must be registers, but the size value can be a numerical value. For example, to reference the value 20 from the values array shown, you would use the following instructions:
movl $2, %edimovl values(, %edi, 4), %eax
This instruction loads the third index value of 4 bytes from the values label to the EAX register (remember, the array starts with index 0). Most often, you will use a register counter as the index value, and change that value to match the array element you need to work with.
Using indirect addressing with registers
Besides holding data, registers can also be used to hold memory addresses. When a register holds a memory address, it is referred to as a pointer. Accessing the data stored in the memory location using the pointer is called indirect addressing.
While using a label references the data value contained in the memory location, you can get the memory location address of the data value by placing a dollar sign ($) in front of the label in the instruction. Thus the instruction
movl $values, %edi
is used to move the memory address the values label references to the EDI register.
movl %ebx, (%edi)
is the other half of the indirect addressing mode. Without the parentheses around the EDI register, the instruction would just load the value in the EBX register to the EDI register. With the parentheses around the EDI register, the instruction instead moves the value in the EBX register to the memory location contained
in the EDI register.
Instead of just allowing you to add a value to the register, you must place the value outside of the parentheses, like so:
movl %edx, 4(%edi)
This instruction places the value contained in the EDX register in the memory location 4 bytes after the location pointed to by the EDI register. You can also go in the opposite direction:
movl %edx, -4(&edi)
This instruction places the value in the memory location 4 bytes before the location pointed to by the EDI register.
Conditional Move Instructions
A whole host of instructions are included in the conditional move instruction set. All of the instructions have the format
cmovx source, destination
where x is a one- or two-letter code denoting the condition that will trigger the move action. The conditions are based on the current values in the EFLAGS register. The specific bits that are used by the conditional move instructions are shown in the following table.
EFLAGS Bit
Name
Description
CF
Carry flag
A mathematical expression has created a
carry or borrow
OF
Overflow flag
An integer value is either too large or too
small
PF
Parity flag
The register contains corrupt data from a
mathematical operation
SF
Sign flag
Indicates whether the result is negative or
positive
ZF
Zero flag
The result of the mathematical operation
is zero
The conditional move instructions are grouped together in pairs, with two instructions having the same meaning.For example, a value can be above another value, but it can also be not below or equal to the value. Both conditions are equivalent, but both have separate conditional move instructions.
The following table shows the unsigned conditional move instructions.
Instruction Pair
Description
EFLAGS Condition
CMOVA/CMOVNBE
Above/not below or equal
(CF or ZF) = 0
CMOVAE/CMOVNB
Above or equal/not below
CF=0
CMOVNC
Not carry
CF=0
CMOVB/CMOVNAE
CMOVB/CMOVNAE
CF=1
CMOVC
Carry
CF=1
CMOVBE/CMOVNA
Below or equal/not above
(CF or ZF) = 1
CMOVE/CMOVZ
Equal/zero
ZF=1
CMOVNE/CMOVNZ
Not equal/not zero
ZF=0
CMOVP/CMOVPE
Parity/parity even
PF=1
CMOVNP/CMOVPO
Not parity/parity odd
PF=0
As you can see from the table, the unsigned conditional move instructions rely on the Carry, Zero, and Parity flags to determine the difference between two operands. If the operands are signed values, a different set of conditional move instructions must be used, as shown in the following table.
Instruction Pair
Description
EFLAGS Condition
CMOVGE/CMOVNL
Greater or equal/not less
(SF xor OF)=0
CMOVL/CMOVNGE
Less/not greater or equal
(SF xor OF)=1
CMOVLE/CMOVNG
Less or equal/not greater
((SF xor OF) or ZF)=1
CMOVO
Overflow
OF=1
CMOVNO
Not overflow
OF=0
CMOVS
Sign (negative)
SF=1
CMOVNS
Not sign (non-negative)
SF=0
The signed conditional move instructions utilize the Sign and Overflow flags to indicate the condition of the comparison between the operands.
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/48729/showart_414050.html |
|