Assembly Language Lab (4)
Agenda Direct-Offset Operands Data-Related Operators and Directives Instructions Data Transfer Addition and Subtraction Status Flags JMP & LOOP Conditional JMP & LOOP
Direct-Offset Operands Adding a displacement to the name of a variable (creating a direct-offset operand) is useful when it is needed to access memory locations that may not have explicit label. Adding 1 to the off`set of arrayB .data arrayB BYTE 10h, 20h , 30h, 40h, 50h .code mov al, arrayB ;AL = 10h mov al, [arrayB + 1] ;AL = 20h mov al, [arrayB + 2] ;AL = 30h Adding 2 to the offset of arrayB
Direct-Offset Operands Effective Address arrayB + 1 Dereferencing the expression to obtain the contents of memory at the address [arrayB + 1] The brackets are not required by MASM, so these statements are equivalent mov al, arrayB + 1 mov al, [arrayB + 1]
Exercise (1) INCLUDE Irvine32.inc .data arrayB BYTE 10h, 20h, 30h, 40h, 50h .code main PROC mov al, arrayB mov al, [arrayB + 1] mov al, arrayB + 2 exit main ENDP END main AL = 10h AL = 20h AL = 30h
Adding 2 to the offset of arrayW to access the second element Exercise (2) Adding 2 to the offset of arrayW to access the second element INCLUDE Irvine32.inc .data arrayW WORD 1000h, 2000h, 3000h .code main PROC mov ax, arrayW mov ax, [arrayW + 2] exit main ENDP END main AX = 1000h AX = 2000h
Adding 4 to the offset of arrayD to access the second element Exercise (3) Adding 4 to the offset of arrayD to access the second element INCLUDE Irvine32.inc .data arrayD DWORD 10000000h, 20000000h .code main PROC mov eax, arrayD mov eax, [arrayD + 4] exit main ENDP END main EAX = 10000000h EAX = 20000000h
Direct-Offset Operands Range Checking MASM has no built-in range checking for effective addresses. If we execute the following statement, the assembler just retrieves a byte of memory outside the array. mov al, [arrayB + 20]
Data-Related Operators and Directives
Data-Related Operators and Directives You can use a number of MASM directives to get information about the addresses and size characteristics of data: OFFSET PTR TYPE LengthOf SizeOf
The LENGTHOF operator counts the number of elements in an array OFFSET OFFSET reserved word is an operator that retrieves the offset address of the given variable. The offset represents the distance, in bytes, of the label from the beginning of the data segment PTR You can use the PTR operator to override the declared size of an operand This is only necessary when you’re trying to access the variable using a size attribute that’s different from the one used to declare the variable. TYPE The TYPE operator returns the size, in bytes, of a single element of a variable LENGTHOF The LENGTHOF operator counts the number of elements in an array SIZEOF The SIZEOF operator returns a value that is equivalent to multiplying LENGTHOF by TYPE.
OFFSET Operator INCLUDE Irvine32.inc .data .code main PROC bVal BYTE ? ;bVal located at offset 00404000h wVal WORD ? dVal DWORD ? dVal2 DWORD ? .code main PROC mov esi, OFFSET bVal ; ESI = 00404000 mov esi, OFFSET wVal ; ESI = 00404001 mov esi, OFFSET dVal ; ESI = 00404003 mov esi, OFFSET dVal2 ; ESI = 00404007 exit main ENDP END main
PTR Operator Move the lower 16 bits of a doubleword variable named myDouble into AX. .data myDouble DWORD 12345678h .code mov ax,myDouble ; error mov ax,WORD PTR myDouble
TYPE Operator .data var1 BYTE ? var2 WORD ? var3 DWORD ? var4 QWORD ? .code mov al, type var1 ; al = 01h mov al, type var2 ; al = 02h mov al, type var3 ; al = 04h mov al, type var4 ; al = 08h
LengthOf & SizeOf Operators .data array word 1000h, 2000h, 3000h .code mov al, lengthOf array ; al = 03h mov al, sizeOf array ; al = 06h
Addition and Subtraction Instructions: Data Transfer Addition and Subtraction
Zero Extension of Integers MOVZX Instruction The MOVZX instruction (move with zero-extend) copies the contents of a source operand into a destination operand and zero-extends the value to 16 or 32 bits. MOVZX dest, source 10001111 source 00000000 10001111 dest
Zero Extension of Integers MOVZX Instruction It is only used with unsigned integers. There are three variants: MOVZX reg32, reg/mem8 MOVZX reg32, reg/mem16 MOVZX reg16, reg/mem8
Exercise (4) INCLUDE Irvine32.inc .code main PROC mov bx, 0A69Bh movzx eax, bx movzx edx, bl movzx cx, bl exit main ENDP END main BX = A69Bh EAX = 0000A69Bh EDX = 0000009Bh CX = 009Bh
Sign Extension of Integers MOVSX Instruction The MOVSX instruction (move with sign-extend) copies the contents of a source operand into a destination operand and sign-extends the value to 16 or 32 bits. MOVSX dest, source 10001111 source 11111111 10001111 dest
Sign Extension of Integers MOVSX Instruction It is only used with signed integers. There are three variants: MOVSX reg32, reg/mem8 MOVSX reg32, reg/mem16 MOVSX reg16, reg/mem8
Exercise (5) INCLUDE Irvine32.inc .code main PROC mov bx, 0A69Bh movsx eax, bx movsx edx, bl mov bl, 7Bh movsx cx, bl exit main ENDP END main BX = A69Bh EAX = FFFFA69Bh EDX = FFFFFF9Bh BL = 7Bh CX = 007Bh
XCHG Instruction XCHG dest, source The XCHG (exchange data) instruction exchanges the contents of two operands. There are three variants: XCHG reg, reg XCHG reg, mem XCHG mem, reg XCHG dest, source
XCHG Instruction XCHG Instruction Examples xchg ax, bx ;exchange 16-bit registers xchg ah, al ;exchange 8-bit registers xchg var1, bx ;exchange 16-bit memory operand with BX xchg eax, ebx ;exchange 32-bit registers
Exercise (6) INCLUDE Irvine32.inc .data val1 WORD 1000h .code main PROC mov ax, val1 xchg ax, val2 mov val1, ax exit main ENDP END main AX = 1000h AX = 2000h, val2 = 1000h val1 = 2000h
Addition and Subtraction INC and DEC Instructions The INC (increment) and DEC (decrement) instructions, respectively, add 1 and subtract 1 from a single operand. The syntax is: INC reg/mem DEC reg/mem
Addition and Subtraction INC and DEC Instructions Examples .data myWord WORD 1000h .code inc myWord mov bx, myWord dec bx myWord = 1001h BX = 1001h BX = 1000h
Addition and Subtraction NEG Instruction The NEG (negate) instruction reverses the sign of a number by converting the number to its two’s complement. The following operands are permitted: NEG reg NEG mem
Rval = - Xval + (Yval - Zval) Hands On: Exercise (7) Write the code that implements the following arithmetic expression: Rval = - Xval + (Yval - Zval) , where Xval = 26, Yval = 30, and Zval = 40 X = 0001 1010b Y = 0001 1110b Z = 0010 1000b
Exercise (7) INCLUDE Irvine32.inc .data Rval SDWORD ? Xval SDWORD 26 Yval SDWORD 30 Zval SDWORD 40 .code main PROC mov eax, Xval neg eax mov ebx, Yval sub ebx, Zval add eax, ebx mov Rval, eax exit main ENDP END main
Status Flags
Flags Affected by Addition and Subtraction When executing arithmetic instructions, we often want to know something about the result. Is it negative, positive, or zero? Is it too large or too small to fit into the destination operand? Answers to such questions can help us detect calculation errors that might otherwise cause erratic program behaviour. We use the values of CPU status flags to check the outcome of arithmetic operations. We also use status flag values to activate conditional branching instructions, the basic tools of program logic.
Indicates that an operation produced zero. Zero Flag (ZF) Indicates that an operation produced zero. If an operand is subtracted from another of equal value, the Zero flag is set. Carry Flag (CF) Indicates unsigned integer overflow. If an instruction has an 8-bit destination operand but the instruction generates a result larger than 11111111 binary, the Carry flag is set. Auxiliary Carry Flag (AC) Is set when a 1 bit carries out of position 3 in the least significant byte of the destination operand. Is primarily used in binary coded decimal (BCD) arithmetic, but can be used in other contexts
Indicates that an operation produced a negative result. Parity Flag (PF) Is set when the least significant byte of the destination has an even number of 1 bits, immediately after an arithmetic or Boolean instruction has executed. Sign Flag (SF) Indicates that an operation produced a negative result. It is set when the result of a signed arithmetic operation is negative. In other words, if the most significant bit (MSB) of the destination operand is set, the Sign flag is set. The Overflow Flag (OF) Iindicates signed integer overflow. It is set when the result of a signed arithmetic operation overflows or underflows the destination operand.
Zero Flag INCLUDE Irvine32.inc .code main PROC mov ecx, 1 sub ecx, 1 ; ECX = 0, ZF = 1 mov eax, 0FFFFFFFFh inc eax ; EAX = 0, ZF = 1 ; EAX = 1, ZF = 0 dec eax exit main ENDP END main
Carry Flag – Addition INCLUDE Irvine32.inc .code main PROC mov al, 0FFh add al, 1 ; AL = 00, CF = 1 mov ax, 00FFh add ax, 1 ; AX = 0100h, CF = 0 mov ax, 0FFFFh ; AX = 0000, CF = 1 exit main ENDP END main
Carry Flag – Subtraction A subtract operation sets the Carry flag when a larger unsigned integer is subtracted from a smaller one. 00000001 1 00000001 1 00000010 2 11111110 -2 The carry out of bit 7 is inverted and placed in the Carry flag, so CF = 1 CF 1 11111111 FFh
Carry Flag – Subtraction INCLUDE Irvine32.inc .code main PROC mov al, 1 sub al, 2 ; AL = FFh, CF = 1 exit main ENDP END main
Carry Flag The INC and DEC instructions do not affect the Carry flag. Applying the NEG instruction to a nonzero operand always sets the Carry flag.
Auxiliary Carry Flag 00000001 1 00001111 0Fh 1 00010000 10h AC 00000001 1 The sum (10h) contains a 1 in bit position 4 that was carried out of bit position 3 00001111 0Fh AC 1 00010000 10h INCLUDE Irvine32.inc .code main PROC mov al, 0Fh add al, 1 ; AC = 1 exit main ENDP END main
Parity Flag After the ADD, AL contains binary 10001110 (four 0 bits and four 1 bits), and PF = 1 INCLUDE Irvine32.inc .code main PROC mov al, 10001100b add al, 00000010b ; AL = 10001110, PF = 1 sub al, 10000000b ; AL = 00001110, PF = 0 exit main ENDP END main After the SUB, AL contains binary 00001110 (five 0 bits and three 1 bits), and PF = 0
the Sign flag is a copy of the destination operand’s high bit INCLUDE Irvine32.inc .code main PROC mov eax, 4 sub eax, 5 ; EAX = -1, SF = 1 mov bl, 1 ; BL = 01h sub bl, 2 ; BL = FFh, SF = 1 exit main ENDP END main
Overflow Flag For example, the largest possible integer signed byte value is +127; adding 1 to it causes overflow, as the destination operand value does not hold a valid arithmetic result, and the Overflow flag is set: mov al, +127 add al, 1 ; OF = 1 Similarly, the smallest possible negative integer byte value is -128. Subtracting 1 from it causes underflow, and the Overflow flag is set: mov al, -128 sub al, 1 ; OF = 1
Overflow Flag – Addition Test There is a very easy way to tell whether signed overflow has occurred when adding two operands. Overflow occurs when: Two positive operands generate a negative sum. Two negative operands generate a positive sum. Overflow never occurs when the signs of two addition operands are different.
Overflow Flag – Overflow Detection OF = CF XOR high bit of result We show that adding the 8-bit binary integers 10000000 and 11111111 produces : 01111111 and CF = 1 so the resulting MSB = 0. In other words, 1 XOR 0 produces OF = 1. OF = CF XOR high bit of result = 1 XOR 0 = 1 10000000 11111111 CF 1 01111111
Overflow Flag – Overflow Detection The NEG instruction produces an invalid result if the destination operand cannot be stored correctly. For example, if we move -128 to AL and try to negate it, the correct value +128 will not fit into AL. The Overflow flag is set, indicating that AL contains an invalid value: mov al, -128 ; AL = 10000000b neg al ; AL = 10000000b, OF = 1 On the other hand, if 127 is negated, the result is valid and the Overflow flag is clear: mov al, +127 ; AL = 01111111b neg al ; AL = 10000001b, OF = 0
Overflow Flag – Overflow Detection How does the CPU know whether an arithmetic operation is signed or unsigned? We can only give what seems a dumb answer: It doesn’t! The CPU sets all status flags after an arithmetic operation using a set of boolean rules, regardless of which flags are relevant. You (the programmer) decide which flags to interpret and which to ignore, based on your knowledge of the type of operation performed.
Read and Write values to User
ReadDec Reads a 32-bit unsigned decimal integer from the keyboard and returns the value in EAX ReadInt Reads a 32-bit signed decimal integer from the keyboard and returns the value in EAX WriteDec Writes a 32-bit unsigned integer to the console window in decimal format with no leading zeros. Pass the integer in EAX register. WriteInt Writes a 32-bit signed integer to the console window in decimal format with no leading zeros. Pass the integer in EAX register.
ReadChar WriteChar WriteString Reads a single character from the keyboard and returns the character in the AL register. The character is not echoed in the console window WriteChar Writes a single character to the console window. Pass the character (or its ASCII code) in AL register WriteString Writes a null-terminated string to the console window. Pass the string’s offset in EDX register
Write String Call Crlf An Irvine function that prints new line. .data prompt BYTE "Enter your name: ",0 .code mov edx,OFFSET prompt call WriteString
JMP and LOOP Instructions
JMP and LOOP Instructions By default, the CPU loads and executes programs sequentially. But the current instruction might be conditional, meaning that it transfers control to a new location in the program based on the values of CPU status flags (Zero, Sign, Carry, etc.). A transfer of control (jump), or branch, is a way of altering the order in which statements are executed Assembly language programs use conditional instructions to implement high-level statements such as IF statements and loops
JMP Instruction JMP destination The JMP instruction causes an unconditional transfer to a destination, identified by a code label that is translated by the assembler into an offset (address). When the CPU executes an unconditional transfer, the offset of destination is moved into the instruction pointer (EIP), causing execution to continue at the new location. JMP destination
JMP Instruction The JMP instruction provides an easy way to create a loop by jumping to a label at the top of the loop: JMP is unconditional, so a loop like this will continue endlessly unless another way is found to exit the loop. top: … jmp top ; repeat the endless loop
CMP destination, Source CMP Instruction The CMP instruction compares the destination operand to the source operand. It performs an implied subtraction of a source operand from a destination operand. Neither operand is modified. CMP is a valuable tool for creating conditional logic structures. CMP destination, Source
Destination < source Destination > source CMP Instruction When two unsigned operands are compared, the Zero and Carry flags indicate the following relations between operands. CMP Results ZF CF Destination < source 1 Destination > source Destination = source
CMP Instruction mov ax, 5 cmp ax, 10 ZF = 0, CF = 1 mov ax, 1000 mov cx, 1000 cmp cx, ax ZF = 1, CF = 0 mov si, 105 cmp si, 0 ZF = 0, CF = 0
Destination < source Destination > source CMP Instruction When two signed operands are compared, the Sign, Zero and Overflow flags indicate the following relations between operands. CMP Results Flags Destination < source SF ≠ OF Destination > source SF = OF Destination = source ZF = 1
Conditional Jumps
Conditional Structures Two Steps are involved in executing a conditional statement Comparison Jump An operation such as CMP, AND or SUB modifies the CPU status flags Conditional jump instruction tests the flags and causes a branch to a new address
Conditional Jump Instructions A conditional jump instruction branches to a destination label when a status flag condition is true. If the flag condition is false, the instruction immediately following the conditional jump is executed.
Conditional Jump Instructions The following table shows the conditional Jump instructions. Relation For Unsigned Data For Signed Data Equal/Zero JE/JZ Not Equal/ Not Zero JNE/ JNZ Above/ Greater JA/JNBE JG/JNLE Above or Equal/ Greater or Equal JAE/JNB JGE/JNL Below/ Less JB/JNAE JL/JNGE Below or Equal/ Less or Equal JBE/JNA JLE/JNG JNBE Not Below or Equal JNLE Not Less or Equal
Hands On Write an Assembly code that takes two unsigned integers X & Y from the user and prints the relation between those integers: X is Above Y X is Below Y X is Equal Y
INCLUDE Irvine32.inc .data strAbove byte "X is above Y", 0 strBelow byte "X is below Y", 0 strEqual byte "X is equal Y", 0 x dword ? y dword ? .code main PROC call ReadDec mov x, eax mov y, eax cmp x, eax ;eax still has y value ja above jb below je equal above: ;handle above case mov edx, offset strAbove call writesSring jmp next below: ;handle below case mov edx, offset strBelow call writeString equal: ;handle equal case mov edx, offset strEqual next: call CrLf exit main ENDP END main
mov eax, i while: cmp eax, j jna endwhile add x, eax dec eax jmp while Statement In High level language In Assembly IF-ELSE If ( i == j ) { X = 10; } else Y = 10; mov eax, i cmp eax, j jne else mov X, 10 jmp endif else: Mov Y, 10 endif: mov eax, i while: cmp eax, j jna endwhile add x, eax dec eax jmp while endwhile: mov i, eax IF If ( i > j ) { X = 5; } Y = 5; mov eax, i cmp eax, j Jna endif mov X, 5 endif: mov Y, 5 While Loop While ( i > j ) { x += i; i--; }
To be announced on Piazza Assignment To be announced on Piazza
Questions?