Data Transfer and Arithmetic Instructions
Data Transfer and Arithmetic Instructions
Statement Purpose:
In this lab, student will know about the almost each and every Data transfer instructions including memory to register and vice versa transfers, inter-register transfer, and memory to memory transfers. They will also be introduced instruction performing simple arithmetic operations.
Activity Outcomes:
This lab teaches you the following topics:
- Understand how data is transferred inside the system during program run
- What transfer modes are allowed?
- Data transfer
- How arithmetic is performed inside CPU?
- How EFLAG register is affected by various arithmetic instructions?
- How to execute arithmetic instructions at Assembly programming level?
Instructor Note:
As pre-lab activity, read Chapter 4 from the book (Assembly Language for X86 processors, KIP
- IRVINE., 7th Edition (2015), Pearson), and also as given by your theory instructor
Introduction
Assembly language consists of various types of instructions. Data transfer instructions are very important and these instructions moves data from registers to memory and vice versa. Data transfer instructions also allows data movements within the registers. These comes in various flavors like
MOV,MOVZX, MOVSX, XCHG etc.
MOV, a data transfer instruction, copies a source operand to a destination operand. The MOVZX instruction zero-extends a smaller operand into a larger one. The MOVSX instruction sign- extends a smaller operand into a larger register. The XCHG instruction exchanges the contents of two operands. At least one operand must be a register.
The following arithmetic instructions are important:
- The INC instruction adds 1 to an
- The DEC instruction subtracts 1 from an
- The ADD instruction adds a source operand to a destination operand.
- The SUB instruction subtracts a source operand from a destination operand.
- The NEG instruction reverses the sign of an
When converting simple arithmetic expressions to assembly language, use standard operator precedence rules to select which expressions to evaluate first.
The following CPU status flags are affected by arithmetic operations:
- The Sign flag is set when the outcome of an arithmetic operation is
- The Carry flag is set when the result of an unsigned arithmetic operation is too large for the destination operand.
- The Parity flag indicates whether or not an even number of 1 bits occurs in the least significant byte of the destination operand immediately after an arithmetic or boolean instruction has executed.
- The Auxiliary Carry flag is set when a carry or borrow occurs in bit position 3 of the destination
- The Zero flag is set when the outcome of an arithmetic operation is
- The Overflow flag is set when the result of an signed arithmetic operation is too large for the destination operand. In a byte operation, for example, the CPU detects overflow by exclusive-ORing the carry out of bit 6 with the carry out of bit 7.
Activities:
Activity 1:
Write a program that uses addition and subtraction to set and clear the Zero and Sign flags. After each addition or subtraction instruction, insert the call DumpRegs statement to display the registers and flags. Using comments, explain how (and why) the Zero and Sign flags were affected by each instruction.
Solution:
INCLUDE Irvine32.inc
.data
.code
main PROC
mov al,1 ; AL=1
sub al,1 ; AL=0, SF=0, ZF=1
call DumpRegs
sub al,1 ; AL=-1, SF=1, ZF=0
call DumpRegs
add al,1 ; AL=0, SF=0, ZF=1
call DumpRegs
add al,1 ; AL=1, SF=0, ZF=0
call DumpRegs
exit
main ENDP END main
Activity 2
:Write a program that uses addition and subtraction to set and clear the Overflow flag. After each addition or subtraction instruction, insert the call DumpRegs statement to display the registers and flags. Using comments, explain how (and why) the Overflow flag was affected by each instruction. Optional: include an ADD instruction that sets both the Carryand Overflow flags.
Solution:
INCLUDE Irvine32.inc
.data
.code
main PROC
mov al,+127 ; AL=7Fh
add al,1 ; AL=80h, OF=1 call DumpRegs
sub al,1 ; AL=7Fh, OF=1 call DumpRegs
sub al,1 ; AL=7Eh, OF=0 call DumpRegs
mov al,-128 add al,-1
call DumpRegs ; AL=7Fh, OF=1
; Optional:
mov al,80h
add al,80h ; AL=0, CF=1, OF=1
call DumpRegs
exit main ENDP END main
Activity 3
:Write instructions that use direct-offset addressing to move the four values in Uarray to the EAX, EBX, ECX, and EDX registers. When you follow this with a call DumpRegs statement, the following register values should display:
EAX=00001000 EBX=00002000 ECX=00003000 EDX=00004000
Next, write instructions that use direct-offset addressing to move the four values in Sarray to the EAX, EBX, ECX, and EDX registers. When you follow this with a call DumpRegs statement, the following register values should display:
EAX=FFFFFFFF EBX=FFFFFFFE ECX=FFFFFFFD EDX=FFFFFFFC
Solution:
INCLUDE Irvine32.inc
.data
Uarray WORD 1000h,2000h,3000h,4000h Sarray SWORD -1,-2,-3,-4
.code
main PROC
; Move with zero extension:
movzxeax,Uarray movzxebx,Uarray+2
movzxecx,Uarray+4 movzxedx,Uarray+6 call DumpRegs
; Move with sign extension:
movsxeax,Sarray movsxebx,Sarray+2 movsxecx,Sarray+4 movsxedx,Sarray+6 call DumpRegs
exit main ENDP END main
Activity 4:
Use a loop with indirect or indexed addressing to reverse the elements of an integer array in place. Do not copy the elements to any other array. Use the SIZEOF, TYPE, and LENGTHOF operators to make the program as flexible as possible if the array size and type should be changed in the future. Optionally, you may display the modified array by calling the DumpMem method from the Irvine32 library.
Solution
INCLUDE Irvine32.inc
.data
array DWORD 1,2,3,4,5,6,7,8,9
.code
main PROC
; point to the first and last array elements
mov | esi,0 | ; beginning of array |
mov | edi,SIZEOF array – TYPE array | ; end of array |
mov | ecx,LENGTHOF array / 2 | ; loop (N / 2) times |
L1:
; The loop swaps array elements from both ends, gradually
; moving towards the center element.
; exchange array[esi] with array[edi], using indexed addressing.
mov | edx,array[esi] | ; temp = array[esi] |
mov mov mov | eax,array[edi] array[esi],eax array[edi],edx | ; array[esi] = array[edi]
; array[edi] = temp |
add |
esi,TYPE array |
; first pointer moves forward |
sub
loop |
edi,TYPE array
L1 |
; second pointer backs up |
; optional: display the array
mov esi,OFFSET array mov ecx,LENGTHOF array mov ebx,TYPE array
call DumpMem
exit main ENDP END main
Home Activities:
Home Task 1:
Write a program that uses a loop to calculate the first seven values in the Fibonacci number sequence { 1,1,2,3,5,8,13 }. Place each value in the EAX register and display it with a call DumpRegs statement inside the loop.
Home Task 2:
Write a program that implements the following arithmetic expression: EAX = -val2 + 7 – val3 + val1
In comments next to each instruction, write the hexadecimal value of EAX. Insert a call DumpRegs statement at the end of the program.
Home Task 3:
Write a program using the LOOP instruction with indirect addressing that copies a string from source to target, reversing the character order in the process.
If your program works correctly, you will see the following sequence of hexadecimal bytes on the screen when the program runs:
67 6E 69 72 74 73 20 65 63 72 75 6F 73 20 65 68
74 20 73 69 20 73 69 68 54
Demonstrate the home activities and Viva voce