EE-314 Spring 2001 Homework #5 Answer Key Due: 03/16/2001 Problem 1) Consider the following fragment of 8088 assembly language code: label: mov xor mov mov add loop cx,8 ax,ax si,ax stuff[si],ax si,2 label ;4 ;3 ;2 ;9+9+4=22 ;4 ;17/5 1a) (20 Points) How many clock cycles does this sequence of instructions take to execute on an 8088 processor? Assume that DS is loaded with the correct segment address, so that no segment overrides are required to access the array ‘stuff’. Answer: The code before the loop takes (4+3+2) = 9 clock cycles. The body of the loop takes (22+4) = 26 clock cycles. The loop executes 8 times, so for 7 of those iterations, the loop instruction will take 17 cycles. On the final iteration of the loop, it will take 5. So the total time will be: (9 + 8*26 + 7*15 + 5) = 341 clock cycles. __________341__________________ 1b) (5 Points) Assuming that the clock frequency of the machine is 4.77 Mhz, how long (e.g. how many microseconds) will the above sequence of instructions take to execute? Answer: The time is the clock period times the number of clock cycles: (1/4.77*10^6)*341 _____71.488 us________ Problem 2) When the assembler encodes the instruction: MOV DX,VAR[BX+DI], The resulting machine code will occupy 4 bytes of memory. The bytes will be as follows: [opcode] [mod reg r/m] [low byte of offset of VAR] [high byte of offset of VAR] 2a) (5 Points) What will be the value encoded by the assembler for the opcode byte (i.e. what will be the value (in hex) of the first byte of the encoded instruction)? ______8Bh_________ 2b) (10 Points)What will be the value encoded by the assembler for the [mod reg r/m] byte (i.e. what will be the value (in hex) of the second byte of the encoded instruction)? ______91h__________ Problem 3) (10 Points) The following shows two different instruction which will set the DX register to 0. What is the difference in code size and execution time of the two instructions on an 8088 processor? EE-314 Spring 2001 xor dx,dx 2 bytes, 3 clock cycles mov dx,0: 3 bytes, 4 clock cycles Problem 4) (25 Points) Write a DOS assembly language program that accepts a single character parameter on the command line. It will parse the command parameter from the command line. If the user entered an ‘A’, it will print the message “Command A entered”. If the user entered a ‘B’, it will print the message “Command B entered”. Otherwise, it prints the message “Invalid Command”. Answer: cmdcnt cmdlin equ equ 80h 81h ;offset of command line length ;offset of command line characters _DATA segment segpsp dw ? msgCmdA msgCmdB msgErr db db db “Command A entered”,0Dh,0Ah,’$’ “Command B entered”,0Dh,0Ah,’$’ “Invalid Command”,0Dh,0Ah,’$’ _DATA ends _STCK segment stck dw 128 dup (?) label word _STCK ends _TEXT segment assume start: mov ax,seg _DATA mov ds,ax assume ds:_DATA mov segpsp,es mov es,ax assume es:_DATA public byte ‘DATA’ ;variable to hold PSP address stack ‘STCK’ public byte ‘CODE’ cs:_TEXT,ds:NOTHING,es:NOTHING ; ; Parse the command line looking for a valid parameter mov es,segpsp assume es:NOTHING mov si,cmdlin ;SI points to command line chars prs10: mov al,es:[si] ;get next char and inc pointer inc si cmp al,0Dh ;check for end of line jz prs90 ;end of line, go print message cmp al,20h ;check for space jz prs10 ;skip spaces ; cmp al,’A’ ;was an A entered jnz prs20 ;if not, see if it’s a B EE-314 Spring 2001 ; ; We found an A on the command line mov dx,offset msgCmdA jmp prs40 prs20: cmp jnz al,’B’ prs80 ;was a B entered ;if not, we have an error ; ; We found a B on the command line mov dx,offset msgCmdB jmp prs40 ; ; We have seen a valid command parameter. Now check that ; there is nothing else on the command line which is invalid. prs40: mov al,es:[si] inc si cmp al,0Dh, jz prs90 cmp al,20h jnz prs80 jmp prs40 ; ; The user entered an invalid command prs80: mov dx,offset msgErr ; ; Print the appropriate message and get out. prs90: mov ah,9 ;DOS print string function ;message pointer is already in DX int 21h ; ; All done mov ax,4C00h int 21h _TEXT ends end start Problem 5) (25 Points) Assume that there is a D/A converter attached to a data port at port address 378h. Write an assembly language subroutine that will generate a sawtooth wave with a frequency of 100Hz and a peak to peak amplitude of 200, using 100 equally spaced samples for each period of the output wave. (Hint: you will probably want to write a time delay function using a delay loop that generates an appropriate amount of delay between output samples). Answer: To generate the ramp output, it is necessary to write successive values to the D/A converter attached to the output port. Since the output is specified as having 100 equally spaced values, with an output range of 200, the increment between successive output values is 2. In order for the output ramp to be a linear slope with the correct frequency, the output values need to be written to the port at an appropriate constant rate. The rate at which the samples are written will be determined by the amount of time taken for each EE-314 Spring 2001 iteration of the loop. The specified output frequency is 100HZ (each period of the wave takes 1/100 sec. or 10 msec). This period is to contain 100 equally spaced output samples, so the samples must be spaced by 10 msec / 100 or 100 microseconds. Therefore, to generate the correct output frequency, it is necessary to code a loop that takes exactly 100 microseconds to execute. Each pass through this loop will generate and emit one sample. labl10: labl15: mov xor dx,378h bl,bl mov out add cmp jb xor nop nop nop al,bl dx,al bl,2 bl,200 labl20 bl,bl ;2 ;8 ;4 ;4 ;16 ; ; ; ; mov loop cx,dlycnt labl40 ;4 ;17/5 jmp labl10 ;15 / 4 3 3 3 3 labl20: labl40: Note the code at labl15. This code checks to see if the sample value in BL has reached the limit and resets it to zero when so. This uses a conditional jump to branch around the code which resets BL to 0. A conditional jump instruction takes 16 clock cycles to execute if the jump is taken and 4 if the jump is not taken. The purpose of the three nop instructions following the xor bl,bl (which resets the sample value to 0) is to ensure that the same amount of time is used whichever branch of the conditional jump is taken. Both paths take 16 clock cycles. This code contains two nested loops. The outer loop generates and emits each successive sample in the output wave. The inner loop (which is made up of the loop instruction at location labl40) causes a delay whose time is dependent on the value, dlycnt, loaded into CX. Not counting the loop instruction, the time taken by the rest of the outer loop is: (2 + 8 + 4 + 4 + 16 + 4 + 15) = 53. Each iteration of the outer loop must take 800 clock cycles. The fixed overhead of the loop is 53 clock cycles. Therefore, the loop instruction at labl40 must take the remaining 800 – 53 = 747 clock cycles. The loop instruction will take 14*(dlycnt – 1) + 5 clocks. If dlycnt is set to 747/17 = 43, then the loop at labl40 will take 17*42+5 = 719 cycles. This is too few, so try 44. With dlycnt set at 44, the delay loop will take 17*43+5 = 736 clocks. This is still too few, however, if we set dlycnt to 45, the result would be 753, which is too many. If a dlycnt value of 44 is used, the total loop time is 53+736 = 789 clock cycles. This is 11 clock cycles short, so we need to add a couple of instructions following the loop to bring the total up to 800. The following shows the final result: mov dx,378h EE-314 labl10: labl15: Spring 2001 xor bl,bl mov out add cmp jb xor nop nop nop al,bl dx,al bl,2 bl,200 labl20 bl,bl ;2 ;8 ;4 ;4 ;16 ; ; ; ; mov loop cx,dlycnt labl40 ;4 ;17/5 nop nop nop mov bl,bl ;3 ;3 ;3 ;2 jmp labl10 ;15 / 4 3 3 3 3 labl20: labl40: On an 8 Mhz 8088 processor, this loop will generate a new output sample every 100 microseconds.