Chapter 4Data Transfers, Addressing
|
Modified: |
4.1 Data Transfer Instructions
Recall memory hierarchically organized.
Must transfer values between CPU registers and memory.
Review of CPU registers
General 8, 16 and 32 bit register
Pointer and index registers are 32 bit
32 bits addresses 4 Gb
4.1.2 Operand Types
Defined by number of bytes.
4.1.3 Direct Memory Operands
MOV instruction transfers values to/between registers and/or memory.
Example
mov ax, 1234h
Transfer 1234h to AX register.
Example
mov ax, 1234h
mov bx, ax
Transfer 1234h to AX register.
Transfer 1234h to BX register.
Example
mov ax, X
X at address 00000000 with hexadecimal value 000F.
Transfer 000F from address 00000000 to AX register.
00000000 .data
00000000 000F X WORD 15
00000002 0000 Y WORD ?
00000000 .code
00000000 main PROC
00000000 66| A1 mov ax, X
00000000 R
00000006 66| A3 mov Y, ax
00000002 R
exit
00000013 main ENDP
END mainExample
mov Y, ax
Y at address 00000002.
Transfer value from AX register to address 00000002.
4.1.8 Direct-Offset Operands
Arrays start at offset 0.
Other elements stored sequentially in memory at increasing offsets.
ExampleA2E is an array definition of 5 bytes stored sequentially as:
0x00405004 41 42 43 44 45 ABCDE
A2E starts at address 0x00405004
A2E array offsets 0 1 2 3 4 'A' 'B' 'C' 'D' 'E' 41 42 43 44 45 mov al, [A2E+2]
transfers 'C' to AL register.
.data Address 00405004 A2E BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 7812hExample
Z is an array definition of 3 words stored sequentially as:
0x00405008 45 28 8F 53 9A 12 78
Z array in Memory Index 0 1 2 Offset 0 1 2 3 4 5 Value 28 8F 53 9A 12 78 mov ax, [Z+4]
transfers 7812 to AX register.
mov ax, Z[4]
transfers 7812 to AX register.
4.2 Addition and Subtraction
Unsigned Binary Representation
5710 = 001110012 110 = 000000012 12810 = 100000002 410 = 000001002 12710 = 011111112 25510 = 111111112
Two's Complement Representation
Negative numbers only, convert from positive to negative by forming one's complement and adding 1. The following uses 8-bit values.
Invert +1 Binary 1's Comp 2's Comp -5710 = -001110012 = 11000110 = 11000111 = -5710 -410 = -000001002 = 11111011 = 11111100 = -410 -110 = -000000012 = 11111110 = 11111111 = -110 -12710 = -011111112 = 10000000 = 10000001 = -12710 -12810 = -100000002 -> 01111111 -> 10000000 = -12810 -12910 = -100000012 -> 01111110 -> 10000000 != -12910 -25510 = -111111112 -> 00000000 -> 00000001 != -25510
|
CPU Flags
Flags are 1-bit values holding Boolean (logical) values after operations such as Add, Sub, etc. The CPU has a register with flags that indicate the following (other flags will be examined later):
Addition and Subtraction
The add and subtract operation can operate on signed or unsigned
numbers, either 8 or 16-bit operands. The result is the same size as
the operands so it is possible that incorrect results are produced when
the result is too large or small. Remember that subtraction is performed
by addition of a negative number.
- Addition and subtraction of unsigned numbers is
invalid whenever there is a carry out, CF = 1 (CF is carry flag).
The result is valid as an unsigned number when CF=0.
The carry flag is the carry out from the leftmost bit for addition.
For subtraction the carry out is inverted, a natural carry out of 1 is inverted by the CPU to 0 and vice versa.
The result is valid as a signed number when OF=0.
The OF = 0 when the carry into the leftmost bit equals the carry out of the leftmost bit, otherwise OF=1.
Addition/Subtraction Examples
00000000 Carry into and out of leftmost 8 bits 110 000000012 bit equal, OF=0. +8 bits +110 = +000000012 8 bits 210 0000000102 Valid unsigned, CF=0. CF = 0 ZF = 0 Valid signed OF=0. OF = 0 SF = 0 |
Unsigned 11111111 Signed Carry into and out of leftmost. 8 bits 25510 111111112 -1 bit equal, OF=0 +8 bits +110 = +000000012 = +1 8 bits 010 1000000002 0 Invalid unsigned, CF=1. CF = 1 ZF = 1 Valid signed, OF=0. Mov Ah, 255 OF = 0 SF = 0 Add Ah, 1 Ah = 0 |
Unsigned 11111111 Signed Carry into and out of leftmost 8 bits 110 000000012 110 bit equal, OF=0. +8 bits +25510 = +111111112 = +(-110) 8 bits 010 1000000002 0 Invalid unsigned, CF = 1. CF = 1 ZF = 1 Valid signed, OF = 0. Mov Ah, 1 OF = 0 SF = 0 Add Ah, 255 OR Ah = 0 Add Ah, -1 |
Unsigned 11111111 Signed Carry into and out of leftmost
8 bits 110 000000012 110 bit equal, OF=0.
-8 bits -110 = +111111112 -110
8 bits 010 1000000002 0 Valid unsigned, CF=0 since
inverted on subtraction
CF = 0 ZF = 1
Mov Ah, 1 OF = 0 SF = 0 Valid signed, OF=0.
Sub Ah, 1 Ah = 0
|
Unsigned 01111111 Signed Carry into and out of leftmost 8 bits 12710 011111112 12710 bit not equal, OF=1. +8 bits +110 = +000000012 +110 8 bits 12810 0100000002 = -128 Valid unsigned 128, CF=0. CF = 0 ZF = 0 Invalid signed -128, OF=1. Mov Ah, 127 OF = 1 SF = 1 Add Ah, 1 |
Unsigned 10000000 Signed Carry in 0, carry out of leftmost 8 bits 12810 100000002 -12810 bit 1, OF=1. +8 bits +12810 = +100000002 +(-128)10 8 bits 010 1000000002 = 0 Invalid unsigned CF=1. CF = 1 ZF = 1 Invalid signed OF=1. Mov Ah, 128 OF = 1 SF = 0 Add Ah, 128 |
Question - What is CF, OF, ZF and SF?
1.
mov al, 01000000b
add al, 01000000b2. mov al, 01000000b Remember the CF is inverted in subtraction.
sub al, 01000000b
Add and Sub Instructions
Negation Instruction
Negation makes a positive number negative and a negative number positive.For example, -(+1) = -1, -(-1) = +1. Negation only makes sense for signed numbers.
If an 8-bit -128 or a 16-bit -32768 is negated the result is invalid, OF=1. An example is:
Mov Ah, -1 Ah = 11111111 Neg Ah Ah = 00000001
Increment and Decrement Instructions
Increment or decrement by one.The overflow, carry, zero, and sign flags have the same meaning as with addition and subtraction.
Note that incrementing the 8-bit value 255 (or 16-bit 65535) rolls an unsigned number to 0.
However, incrementing a signed number has the sequence of 126, 127, -128, -127, -126.
Example
Mov Ch, 255 Mov Dh, 127 Inc Ch Inc Dh 11111111 01111111 255 11111111 127 0111111 +1 = 00000001 +1 = +0000001 0 100000000 128 01000000 CF=1 Invalid unsigned OF = 1 Invalid signed (carry in ¹ carry out) OF=0 CF = 0
4.2.7 Example Program
TITLE Addition and Subtraction (AddSub3.asm)
; Chapter 4 example. Demonstration of ADD, SUB,
; INC, DEC, and NEG instructions, and how
; they affect the CPU status flags.
; Last update: 06/01/2006
INCLUDE Irvine32.inc
.data
Rval SDWORD ?
Xval SDWORD 26
Yval SDWORD 30
Zval SDWORD 40
.code
main PROC
; INC and DEC
mov ax,1000h
inc ax ; 1001h
dec ax ; 1000h
; Expression: Rval = -Xval + (Yval - Zval)
mov eax,Xval
neg eax ; -26
mov ebx,Yval
sub ebx,Zval ; -10
add eax,ebx
mov Rval,eax ; -36
; Zero flag example:
mov cx,1
sub cx,1 ; ZF = 1
mov ax,0FFFFh
inc ax ; ZF = 1
; Sign flag example:
mov cx,0
sub cx,1 ; SF = 1
mov ax,7FFFh
add ax,2 ; SF = 1
; Carry flag example:
mov al,0FFh
add al,1 ; CF = 1, AL = 00
; Overflow flag example:
mov al,+127
add al,1 ; OF = 1
mov al,-128
sub al,1 ; OF = 1
exit
main ENDPEND main
4.3 Data Related Operators and Directives
4.3.1 OFFSET operator
Returns the OFFSET (the address in protected mode) of a data label.
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017hExample
Above 15 bytes stored sequentially as: X 0x00405000 78 56 34 12
Y 0x00405004 41 42 43 44 45
Z 0x00405009 28 8F 53 9A 17 00
mov eAx, OFFSET Y moves 00405004 to eAx register.
mov eAx, OFFSET Z
moves 00405009 to eAx register.
mov eAx, OFFSET Z[4]
moves 0040500D to eAx register.
X Y Z 00405000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 78 56 34 12 41 42 43 44 45 28 8F 53 9A 17 00 3. Question - What is esi?
mov esi, OFFSET X
mov esi, OFFSET Y[3]
4.4 Indirect Addressing
Indirect addressing used in arrays and accessing parameters in procedures.
4.4.1 Indirect Operands
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017h.codemov esi, OFFSET Y ; esi = 00405004 mov al, [esi] ; al = 'A' mov ah, [esi+1] ; ah = 'B'add esi, 2 ; esi = 00405006 mov cl, [esi] ; cl = 'C'
X Y Z 00405000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 78 56 34 12 41 42 43 44 45 28 8F 53 9A 17 00
4. Question - What is ax?
mov esi, OFFSET Z
mov ax, [esi]
mov esi, OFFSET Y+2
mov al, [esi]
4.4.2 Arrays
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017h.codemov esi, OFFSET Z ; esi = 00405009 mov ax, [esi] ; ax = 8F28h mov bx, [esi+2] ; bx = 9A53h
X Y Z 00405000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 78 56 34 12 41 42 43 44 45 28 8F 53 9A 17 00
5. Question - What is ax?
mov esi, OFFSET Z
mov ax, [esi+4]
mov esi, OFFSET Y
mov ax, [esi+2]
4.4.1 Indexed Operands
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017h.codemov esi, 0 ; esi = 00000000 mov al, Y[esi] ; al = 'A' mov ah, Y[esi+1] ; ah = 'B'
X Y Z 00405000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 78 56 34 12 41 42 43 44 45 28 8F 53 9A 17 00
6. Question - What is ax?
mov esi, 0
mov ax, Z[esi+2]
mov esi, 1
mov ax, Y[esi+2]
Scale Factors
Example
Z values occupy 2 locations of memory.
esi must be incremented by 2 to index the next element.
Or esi increment by 1 and scale by 2, usually clearer code to write and read.
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017h .code mov esi, 0 ; esi = 00000000
mov ax, Z[esi] ; ax = 8F28h
inc esi ; esi = 00000001
mov bx, Z[esi*2] ; bx = 9A53h
|
| X | Y | Z | |||||||||||||
| 00405000 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0A | 0B | 0C | 0D | 0E |
| 78 | 56 | 34 | 12 | 41 | 42 | 43 | 44 | 45 | 28 | 8F | 53 | 9A | 17 | 00 |
7. Question - What is ax?
mov esi, 2
mov ax, Z[esi*2]
4.4.4 Pointers
Variable that holds the address of another variable.
NEAR pointers are 32-bit for protected mode.
Example
P holds the address (OFFSET) of Z, 00405009.
.data Address 00405000 X DWORD 12345678h 00405004 Y BYTE 'ABCDE' 00405009 Z WORD 8F28h, 9A53h, 0017h 0040500F P DWORD Z.codemov esi, P ; esi = 00405009 mov ax, [esi] ; ax = 8F28h
X Y Z P 00405000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 78 56 34 12 41 42 43 44 45 28 8F 53 9A 17 00 09 50 40 00 8. Question - What is ax and bl?
mov esi, P
mov ax, [esi+2]
mov bl, [esi-2]
4.5 JMP and LOOP Instructions
4.5.1 JMP
Fetch/execute cycle increments the program counter to fetch the next sequential instruction in memory for execution.
JMP instructions unconditionally transfer program execution to a non-sequential location in memory.
The example below lists the addresses of the program instructions.
JMP forward
transfers execution by changing the next instruction to fetch from address 00000004 to address 00000008.
00000000 B0 FF mov al, -1
00000002 EB 04 JMP forward
00000004 04 01 add al, 1
00000006 FE C0 inc al
00000008 forward:
00000008 add ah, 5When executing JMP forward, the instruction pointer (EIP) is at address 00000004.
To change EIP to address 00000008, CPU adds the distance to the label:
EIP 00000004
+ 04 + 00000004
EIP 00000008
The example below lists the addresses of the program instructions.
JMP backward
transfers execution by changing the next instruction to fetch from address 00000006 to address 00000002.
00000000 B0 FF mov al, -1
00000002 backward:
00000002 04 01 add al, 1
00000004 EB FC JMP backward
00000006 FE C0 inc alWhen executing JMP backward, the instruction pointer (EIP) is at address 00000006.
To change EIP to address 00000002, the CPU adds the distance to the label, negative because backward JMP:
EIP 00000006
+ FC + FFFFFFFC
EIP 00000002
4.5.2 LOOP instruction
Counting repetition, executing a set of statements a fixed number of times, is common in programming.
The LOOP operation:
decrements ecx if ecx != 0, execution continues at the label.
Example
Output: +5 +4 +3 +2 +1
00000000 B9 00000005 mov ecx, 5
00000005 @do:
00000005 8B C1 mov eax, ecx
00000007 E8 00000000 E call WriteInt
0000000C E2 F7 @while: loop @doecx = 5;
do {
System.out.print( ecx );
ecx--;
} while( ecx != 0);Example - Indexed operands
Sum 32-bit integers and print intermediate sum.
Output: +9 +15 +18 +23 +33
.data
array dword 10, 5, 3, 6, 9
.code
main PROC
mov ecx, 5
mov eax, 0
@do:
add eax, array[ecx*4-4]
call WriteInt
@while: loop @doint array[] = { 10, 5, 3, 6, 9};
ecx = 5;
eax = 0;
do {
eax = array[ecx - 1] + eax;
System.out.print( eax );
ecx--;
} while( ecx != 0);
0 4 8 12 16 0 1 2 3 4 10 5 3 6 9
Example - Indexed operands
Sum 32-bit integers and print intermediate sum.
Output: +10 +15 +18 +24 +33
.data
array dword 10, 5, 3, 6, 9
.code
main PROC
mov ecx, 5
mov esi, 0
mov eax, 0
@do:
add eax, array[esi]
call WriteInt
add esi, 4
@while: loop @doint array[] = { 10, 5, 3, 6, 9};
ecx = 5;
eax = 0;
esi = 0;
do {
eax = array[ esi ] + eax;
System.out.print( eax );
esi++;
ecx--;
} while( ecx != 0);
0 4 8 12 16 0 1 2 3 4 10 5 3 6 9 Example - Copy 32-bit values from one memory area to another
.data
source dword 10, 5, 3, 6, 9
dest dword 5 dup(?)
.code
main PROC
mov ecx, 5
mov esi, OFFSET source
mov edi, OFFSET dest
@do:
mov eax, [esi]
mov [edi], eax
call WriteInt
add esi, 4
add edi, 4
@while: loop @doMemory at start of execution 0x00405000 0a 00 00 00 05 00 00 00 03 00 00 00 06 00
0x0040500E 00 00 09 00 00 00 00 00 00 00 00 00 00 00
0x0040501C 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Memory at end of execution
0x00405000 0a 00 00 00 05 00 00 00 03 00 00 00 06 00
0x0040500E 00 00 09 00 00 00 0a 00 00 00 05 00 00 00
0x0040501C 03 00 00 00 06 00 00 00 09 00 00 00 00 00