Class of October 19, 1996



Keep in mind that the default in assembler is decimal, but the
contents of registers are always stored in hexadecimal.

For example, mov ax,20 moves a 20 decimal into ax, where it
is stored as 0014. It is okay to think of ax as containing 20
decimal until you have to perform register arithmetic, for
example, add ah, 1 will make ax contain 114h. 

The nature of arithmetic changes remarkably within a computer. For
example, consider real numbers. What is the "next" real number after
1.5? 1.505 comes after 1.5, but there are an infinite number of
numbers between 1.5 and 1.505. There are an infinite more real 
numbers than integers. In the computer however, there's always a 
next number, since the computer can only store a finite amount of
information.

Review of the test

(1) Assume you have the following data segment:
	.data
		array_x dw 15h, 25h
		array_y dw 20h, 45h
What will ax equal after the following instructions have executed?
	mov ax,array_x	; ax = 0015
	inc ax		; ax = 0016
	mov ax,array_x+2	; ax = 0025
	add ah, 1		; ax = 0125
	sub ax, array_y	; ax = 0105

(2)This is another program to trace. Trace the segment until it
is finished looping. What will ax, bx and cx equal at each
step? 
				ax		bx		cx
mov ax, 20		;	0014
mov bx, 0		; 			0000
mov cx, 3		;					0003
again: add bx, ax	;			0014
dec ax		;	0013	
loop again		;					0002
; add bx, ax	;			0027
; dec ax		;	0012
; loop again	;					0001
; add bx, ax	;			0039
; dec ax		;	0011
; loop again	;					0000

(3) In this question assume you have the following data segment:
	.data
		array_z dw 250,-100,318,495,9,32,-89,640
(a) Write a program segment to sum all eight numbers in this array
(note that the numbers in array_z might change so your program
must sum whatever numbers are there). When you finish the sum
should be in ax. Your first instruction should be mov ax,0.
	mov ax, 0
	add ax, array_z		; direct
	add ax, array_z+2		; direct with offset
	add ax, array_z+4
	add ax, array_z+6
	add ax, array_z+8
	add ax, array_z+10
	add ax, array_z+12
	add ax, array_z+14

; or you could've done this:
	 mov cx, 8
	 xor ax, ax
	 mov si, offset array_z
adder: add ax, [si]			; indirect
	 inc si
	 inc si				; must add 2 because it's a word
	 loop adder
	
(b) Now suppose you want to sum up every other number in the array.
That is, you want to sum the first number, the third number, and the
fifth number, and the seventh number in this array.
Write the program segment you would use to do this. Your first
instruction should be mov ax, 0.
	mov ax, 0
	add ax, array_z		
	add ax, array_z+4
	add ax, array_z+8
	add ax, array_z+12
; or:
	 mov cx, 4
	 xor ax, ax
	 mov si, offset array_z
adder: add ax, [si]			; indirect
	 add si, 4
	 loop adder

(4) In this question assume you have the following data segment:
	.data
		value1 dw 250
		value2 dw ?
		value3 dw ?
		value4 dw ?
Suppose you have a main program which contains the following
instructions.
		call copy_it
Subroutine copy_it is to copy value1 into variables value2, 
value3, and value4. Write the complete subroutine called copy_it.
(If you use any registers in your subroutine remember to
save them at the beginning and restore them at the end.)
	copy_it proc
	push ax
	mov ax, value1
	mov value2, ax
	mov value3, ax
	mov value4, ax
	pop ax
	return
	end copy_it

(5) In this question you will be using DOS function calls. Write a
program segment which first prints a message to the screen asking the 
user to type a single letter (y or n) and then reads in whatever
letter the user has typed. Also declare any variables in the data
segment that you will use.

.data
  mess db "type a (Y or N)", 0ah, 0dh, "$"
  char db ?

.code
  ; the usual startup stuff...
  mov ah, 9 
  mov dx, offset mess
  int 21h
  mov ah, 0Ch ; It is necessary to clear the keyboard buffer first 
	; or spurious characters may be accepted instead.
  mov al, 1
  int 21h
  mov char, al


-----------------------------------------------------------------------


Extra stuff about question (3)(a)
xor means (a or b) and not (a and b) ("a or b but not both")
a	b	a or b	a and b 	a or b and not (a and b)
		a|b		a&b		(a|b)&(~(a&b))
0	0	0		0		0
0	1	1		0		1
1	0	1		0		1
1	1	1		1		0

The direct addressing shown probably executes twice as fast.

Here's a bad way of doing it.
	add ax,array_z
loc1: add byte ptr loc1-2,2	; adds 2 to the offset byte of 
					; previous instruction


Extra stuff about (4)
To make this subroutine more generic, if you called it like
this:
	mov si, offset value1
	call copy_it
	
it could read like this:
	copy_it proc
	push ax
	mov ax, [si]
	mov [si+2], ax
	mov [si+4], ax
	mov [si+6], ax
	pop ax
	return
	end copy_it

You call a subroutine by saying 
  call sub1
where sub1 is the subroutine name.
This gives control to the subroutine, and loads the stack with
the return address -- the instruction immediately following the call.

Call pushes the return address onto stack (push ip); inside the 
subroutine, the return instruction will automatically pop this 
address off the stack and load it into ip (pop ip).

Therefore, if you fail to do the same number of pops as pushes within
the subroutine, you will not return to the correct location afterwards.

Making a subroutine.


------------------------------------------------------------------------

Review of questions at end of chapter 3.
(1) b - al is 8 bits, var2 is 8 bits
    c - unmatched sizes
    d - unmatched sizes
    h - cannot modify cs
    i - cannot modify ip
    k - memory to memory
    l - can't move immediate value to ds
    m - can't move from 1 segment register to another segment
	  register
(3) Link time
(4) Relocatable. Means your code could be loaded any place in
memory.
(5) BX, BP 
(6) a - register, immediate
    b - register, direct
    c - register, immediate
    d - register, indirect
(7) Tell the assembler how big the memory segment is that will put 
the value in -- what kind of add to do.
(8) a - no
    b - probably not
    c - yes
    d - yes
    e - no
(9) second line:	 al s/be ax
    fourth line: 	 [bl] s/be [bx]
    fifth s/be 	 add byte ptr [bx], 2
    six		needs comma
    inc word ptr dx, the word ptr is not necessary	
    inc [cx] is not allowed