Review of exam.
1. Write a complete function to move the cursor to row 10, column 20.
A complete function is something you can call, and that will return. For example, call cmove.
cmove proc
; save registers
push ax
push bx
push dx
mov ah, 2
mov dh, 10
mov dl, 20
mov bh, 0
int 10h
; Restore registers (in reverse order from how saved)
pop dx
pop bx
pop ax
ret
cmove endp
2. Trace the following
AX BX
mov ax, val1 04A3
mov bx, val2 0192
and ax, 0F4h 00A0
cmp al, bl al = A0, bl = 92
jb L1 al > bl if unsigned,
so no jump
(al < bl if signed)
mov al, bl 0092
jmp exit
L1: mov bl, al
exit
val1 dw 04A3h
val2 dw 0192h
04a3h = 0000 0100 1010 0011
0F4h = 0000 0000 1111 0100
and 0000 0000 1010 0000 (0 and 1 = 0, 0 and 0 = 0, 1 and 1 = 1)
= 00A0
Some notes on jump instructions
-------------------------------
There are many different jump instructions, for example,
JA corresponds to 3 different jumps (assembles to 3 different
instructions): 1 each for
byte (short signed jump -128 to +127 bytes away, using relative address)
word (near jump approx 65,000 bytes forward or backward; jumps
within segment)
doubleword (a doubleword is far jump outside the segment)
Signed vs. Unsigned jumps
-------------------------
jmp mnemonics Greater & Less for signed response; (ex. JLE)
use Above and Below for unsigned response. (ex. JBE)
A compare instruction, such as cmp a, b sets some flags. Cmp doesn't "care" whether they are signed or unsigned -- flags for both cases are always set.
The difference comes in in the jump instruction, which looks at differnt flags depending on whether it's a signed or unsigned jump.
Unsigned Signed
JBE JLE
JA (CF=0, ZF=0) JG (ZF=0, SF=0)
Note that you can't use a jmp instruction to call a function if you want
to get back to where you are -- since the call instruction pushes the contents of the ip register (next instruction to execute) onto the stack.
JMP has no affect on the stack, only on the ip register.
3. Assume AX = 0100 1110 0001 0011 (AX = 4e13)
You want to isolate the bit string found in bits 11-7, clearing all except those bits and shift those bits (11-7) to the right of AX, so that AX will = 0000 0000 0001 1100
There are a few different ways of doing this:
(A) Could use shift instructions
mov cl,4
shl ax, cl ; this would get rid of the first 4 bits
; so you would have 1110 0001 0011 0000
mov cl, 11
shr ax, cl ; pushes them off to the right, yeilding the desired answer
(B) And it with some value, then shift
and ax, 0F80 (0000 1111 1000 0000) (or: and ax, 0E00 (0000 1110 0000 0000)
; now we would have 0000 1110 0000 0000
mov cl, 7
shr ax, cl ; yields the desired result
Depending on the kind of operands you are using, AND can consume 2-7 cycles.
Shift may be slower than AND; it takes 3-7 cycles
4. Assume you have the following data segment.
.data
age dw ?
Write a program segment which inspects the unsigned number saved in age and does the following: if that number is between 0 and 10, print word "Child"; if the number is between 11 and 20, print the word "Teenager"; if the number is greater than 20, print "Adult".
must define additional data:
child db "Child", 0AH, 0DH, "$'
teenager db "Teenager", 0AH, 0DH, "$"
adult db "Adult", 0AH, 0DH, "$'
mov ax, age
cmp ax, 10
jbe print_child
cmp ax, 20
jbe print_teen
ja print_adult
jmp last
print_child:
mov dx, offset child
call printout
jmp last
print_teen:
mov dx, offset teenager
call printout
jmp last
print_adult:
mov dx, offest adult
call printout
last:
printout proc
mov ah, 9
int 21h
ret
printout endp
5. Write a program that reverses an array of 10 8-bit integers. Reverse this array in place without making a new array.
Assume all integers are less than 9. Arry db 1h, 4h, 2h, ...
Display the array on screen before and aftter reversal.
One style used to do this was to push the entire array onto the stack and the pop it back off. This is a clever solution, and complete credit was given for this, but it essentially creates another copy of the array in memory, and therefore does not satisfy the criteria.
mov al, arry
mov ah, arry+9
mov arry, ah
mov arry+9, al
mov al, arry+1
mov ah, arry+8
mov arry+8, al
mov arry+1, ah
or, instead:
mov di, offset arry
mov si, di+9
mov cx, 5
mov1: mov al, byte ptr [di]
mov ah, byte ptr [si]
mov [si], al
mov [di], ah
inc di
dec si
loop mov1
In order to display a character, you must first add 30h to the value to be dispalyed.
displ proc
mov di, offset arry
mov 10, cx
L1: mov ah, 2 ; in case ah is changed by the dos call
mov dl, byte ptr [di]
or dl, 30h
int 21h
inc di ; point to the next element in the array
mov dl, 20h ; space character
mov ah, 2
int 21h
loop L1
ret
displ endp
6. Assume the data
.data
buff dw 6 dup (0)
numb dw 23h
dw 2,4,1,0,0
ax bx dx di buff si
mov ax, @data
mov ds, ax what's in ds? Segment address of data
mov ax, numb | 0023
mov si, offset numb | 000C
--------------------------------------------------------------------------
mov di, offset buff | 0000
xor dx, dx | 0000
--------------------------------------------------------------------------
xor ax, ax | 0000
L1: add dx,1 | 0001
--------------------------------------------------------------------------
add ax, [si] | 0023
mov [di], ax | 0023
--------------------------------------------------------------------------
add di, 2 | 0002
add si, 2 | 000E
--------------------------------------------------------------------------
cmp dx, 3 |
jna L1 |
L1: add dx,1 | 0002
--------------------------------------------------------------------------
add ax, [si] | 0025
mov [di], ax | 0025 (buff+2)
--------------------------------------------------------------------------
add di, 2 | 0004
add si, 2 | 0010
--------------------------------------------------------------------------
cmp dx, 3 |
jna L1 |
L1: add dx,1 | 0003
--------------------------------------------------------------------------
add ax, [si] | 0029
mov [di], ax | 0029 (buff+4)
--------------------------------------------------------------------------
add di, 2 | 0006
add si, 2 | 0012
--------------------------------------------------------------------------
cmp dx, 3 |
jna L1 |
L1: add dx,1 | 0004
--------------------------------------------------------------------------
add ax, [si] | 002A
mov [di], ax | 002A (buff+6)
--------------------------------------------------------------------------
add di, 2 | 0008
add si, 2 | 0014
--------------------------------------------------------------------------
cmp dx, 3 |
jna L1 |