Read this article, which gives two examples of instructions set architectures (ISAs). Look over how the different microprocessors address memory. Take note of similarities and differences of format, instructions and type of instructions, and addressing modes between these two as well as between these and the MIPS instructions of the previous sections.
Some of the most important and most frequently used instructions are those that move data. Without them, there would be no way for registers or memory to even have anything in them to operate on.
|mov src, dest||GAS Syntax|
|mov dest, src||Intel Syntax|
mov stands for move. Despite its name the
mov instruction copies the
src operand into the
After the operation both operands contain the same contents.
(into larger register)
(register determines size of retrieved memory)
(up to 32-bit values)
.data value: .long2 .text .globl_start _start: movl$6,%eax# eax ≔ 6 # └───────┐ movw%eax,value# value ≔ eax # └───────────┐ movl$0,%ebx# ebx ≔ 0 │ │ # ┌──┘ │ movb%al,%bl# bl ≔ al │ # %ebx is now 6 │ # ┌─────┘ movlvalue,%ebx# ebx ≔ value movl$value,%esi# ebx ≔ @value # %esi is now the address of value xorl%ebx,%ebx# ebx ≔ ebx ⊻ ebx # %ebx is now 0 movwvalue(,%ebx,1),%bx# bx ≔ value[ebx*1] # %ebx is now 6 # Linux sys_exit movl$1,%eax# eax ≔ 1 xorl%ebx,%ebx# ebx ≔ 0 int$0x80
|xchg src, dest||GAS Syntax|
|xchg dest, src||Intel Syntax|
xchg stands for exchange. The
xchg instruction swaps the
src operand with the
dest operand. It is like doing
destto a temporary (another register),
dest, and finally
except that no register needs to be reserved for temporary storage.
This exchange pattern of three consecutive
mov instructions can be detected by the DFU present in some architectures, which will trigger special treatment. The opcode for
xchg is shorter though.
Any combination of register or memory operands, except that at most one operand may be a memory operand. You cannot exchange two memory blocks.
.data value: .long2 .text .global_start _start: movl$54,%ebx xorl%eax,%eax xchglvalue,%ebx # %ebx is now 2 # value is now 54 xchgw%ax,value # Value is now 0 # %eax is now 54 xchgb%al,%bl # %ebx is now 54 # %eax is now 2 xchgwvalue(%eax),%ax # value is now 0x00020000 = 131072 # %eax is now 0 # Linux sys_exit mov$1,%eax xorl%ebx,%ebx int$0x80
If one of the operands is a memory address, then the operation has an implicit
lock prefix, that is, the exchange operation is atomic. This can have a large performance penalty.
However, on some platforms exchanging two registers will trigger the register renamer. The register renamer is a unit in that merely renames registers, so no data actually have to be moved. This is super fast (branded as “zero-latency”). Renaming registers could be useful since
It is also worth noting that the common
nop (no operation) instruction,
is the opcode for
xchgl %eax, %eax.
|cmpxchg arg2, arg1||GAS Syntax|
|cmpxchg arg1, arg2||Intel Syntax|
cmpxchg stands for compare and exchange. Exchange is misleading as no data are actually exchanged.
cmpxchg instruction has one implicit operand: the
eax depending on the size of
xchg there is no implicit
lock prefix, and if the instruction is required to be atomic,
lock has to be prefixed.
arg2 has to be a register.
arg1 may be either a register or memory operand.
eax) [depending on
OFare altered, too.
The following example shows how to use the
cmpxchg instruction to create a spin lock which will be used to protect the result variable. The last thread to grab the spin lock will get to set the final
value of result:
|example for a spin lock|
|movz src, dest||GAS Syntax|
|movzx dest, src||Intel Syntax|
movz stands for move with zero extension. Like the regular
movz instruction copies data from the
dest operand, but the the remaining bits in
dest that are not provided by
srv are filled with zeros. This instruction is useful for copying
a small, unsigned value to a bigger register.
Dest has to be a register, and
src can be either another register or a memory operand. For this operation to make sense
dest has to be larger than
There are none.
.data byteval: .byte204 .text .global_start _start: movzbwbyteval,%ax # %eax is now 204 movzwl%ax,%ebx # %ebx is now 204 movzblbyteval,%esi # %esi is now 204 # Linux sys_exit mov$1,%eax xorl%ebx,%ebx int$0x80
|movs src, dest||GAS Syntax|
|movsx dest, src||Intel Syntax|
movsx stands for move with sign extension. The
movsx instruction copies the
src operand in the
and pads the remaining bits not provided by
src with the sign bit (the MSB) of
This instruction is useful for copying a signed small value to a bigger register.
movsx accepts the same operands as
movsx does not modify any flags, either.
.data byteval: .byte-24# = 0xe8 .text .global_start _start: movsbwbyteval,%ax # %ax is now -24 = 0xffe8 movswl%ax,%ebx # %ebx is now -24 = 0xffffffe8 movsblbyteval,%esi # %esi is now -24 = 0xffffffe8 # Linux sys_exit mov$1,%eax xorl%ebx,%ebx int$0x80
movsb instruction copies one byte from the memory location specified in
esi to the location specified in
edi. If the direction flag is cleared, then
incremented after the operation. Otherwise, if the direction flag is set, then the pointers are decremented. In that case the copy would happen in the reverse direction, starting at the highest address and moving toward lower addresses until
There are no explicit operands, but
ecxdetermines the number of iterations,
esispecifies the source address,
edithe destination address, and
No flags are modified by this instruction.
section.text ; copy mystr into mystr2 movesi,mystr; loads address of mystr into esi movedi,mystr2; loads address of mystr2 into edi cld; clear direction flag (forward) movecx,6 repmovsb; copy six times section.bss mystr2:resb6 section.data mystrdb"Hello",0x0
movsw instruction copies one word (two bytes) from the location specified in
esi to the location specified in
edi. It basically does the same thing as
with words instead of bytes.
section.code ; copy mystr into mystr2 movesi,mystr movedi,mystr2 cld movecx,4 repmovsw ; mystr2 is now AaBbCca\0 section.bss mystr2:resb8 section.data mystrdb"AaBbCca",0x0
|lea src, dest||GAS Syntax|
|lea dest, src||Intel Syntax|
stands for load effective address. The
lea instruction calculates the address of the
src operand and loads it into the
Load Effective Address calculates its
src operand in the same way as the
mov instruction does, but rather than loading the contents of that address into the
it loads the address itself.
lea can be used not only for calculating addresses, but also general-purpose unsigned integer arithmetic (with the caveat and possible advantage that FLAGS are unmodified). This can be quite powerful, since the
can take up to 4 parameters: base register, index register, scalar multiplier and displacement, e.g.
[eax + edx*4 -4] (Intel syntax) or
-4(%eax, %edx, 4) (GAS syntax). The scalar multiplier is limited
to constant values 1, 2, 4, or 8 for byte, word, double word or quad word offsets respectively. This by itself allows for multiplication of a general register by constant values 2, 3, 4, 5, 8 and 9, as shown below (using NASM syntax):
leaebx,[ebx*2]; Multiply ebx by 2 leaebx,[ebx*8+ebx]; Multiply ebx by 9, which totals ebx*18
|cmovcc src, dest||GAS Syntax|
|cmovcc dest, src||Intel Syntax|
cmov stands for conditional move. It behaves like
mov but the execution depends on various flags. There
are following instruction available:
|CF ∨ ZF||
|SF = OF||
|ZF ∨ SF ≠ OF||
|CF ∨ ZF||
|¬CF||SF = OF|
Dest has to be a register.
Src can be either a register or memory operand.
cmov instruction can be used to eliminate branches, thus usage of
avoids branch mispredictions. However, the
cmov instructions needs to be used wisely: the dependency chain will become longer.
General purpose byte or word transfer instructions:
alusing a table in memory
These are I/O port transfer instructions:
Special address transfer Instructions:
load effective address of operand into specified register
load DS register and other specified register from memory
Flag transfer instructions:
ah with the low byte of flag register
ah register to low byte of flag register
copy flag register to top of stack
copy top of stack word to flag register