ZeePedia Add to Favourites   |   Contact us


Assembly Language Programming

<<< Previous Display Memory: ASCII Codes, Display Memory Formation, Assembly Language Next >>>
 
img
6
Display Memory
The debugger gives a very close vision of the processor. That is why every
program written till now was executed inside the debugger. Also the
debugger is a very useful tool in assembly language program development,
since many bugs only become visible when each instruction is independently
monitored the way the debugger allows us to do. We will now be using the
display screen in character mode, the way DOS uses this screen. The way we
will access this screen is specific to the IBM PC.
6.1. ASCII CODES
The computer listens, sees, and speaks in numbers. Even a character is a
number inside the computer. For example the keyboard is labeled with
characters however when we press `A', a specific number is transferred from
the keyboard to the computer. Our program interprets that number as the
character `A'. When the same number comes on display, the Video Graphics
Adapter (VGA) in our computer shows the shape of `A'. Even the shape is
stored in binary numbers with a one bit representing a pixel on the screen
that is turned on and a zero bit representing a pixel that is not glowing. This
example is considering a white on black display and no colors. This is the
way a shape is drawn on the screen. The interpretation of `A' is performed by
the VGA card, while the monitor or CRT (cathode ray tube) only glows the
pixels on and turns them off. The keyboard has a key labeled `A' and
pressing it the screen shows `A' but all that happened inside was in
numbers.
An `A' on any computer and any operating system is an `A' on every other
computer and operating system. This is because a standard numeric
representation of all commonly used characters has been developed. This is
called the ASCII code, where ASCII stands for American Standard Code for
Information Interchange. The name depicts that this is a code that allows the
interchange of information; `A' written on one computer will remain an `A' on
another. The ASCII table lists all defined characters and symbols and their
standardized numbers. All ASCII based computers use the same code. There
are few other standards like EBCDIC and gray codes, but ASCII has become
the most prevalent standard and is used for Internet communication as well.
It has become the de facto standard for global communication. The character
mode displays of our computer use the ASCII standard. Some newer
operating systems use a new standard Unicode but it is not relevant to us in
the current discussion.
Standard ASCII has 128 characters with assigned numbers from 0 to 127.
When IBM PC was introduced, they extended the standard ASCII and defined
128 more characters. Thus extending the total number of symbols from 128
to 256 numbered from 0 to 255 fitting in an 8-bit byte. The newer characters
were used for line drawing, window corners, and some non-English
characters. The need for these characters was never felt on teletype
terminals, but with the advent of IBM PC and its full screen display, these
semi-graphics characters were the need of the day. Keep in mind that at that
time there was no graphics mode available.
The extended ASCII code is just a de facto industry standard but it is not
defined by an organization like the standard ASCII. Printers, displays, and all
other peripherals related to the IBM PC understand the ASCII code. If the
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
code for `A' is sent to the printer, the printer will print the shape of `A', if it is
sent to the display, the VGA card will form the shape of `A' on the CRT. If it is
sent to another computer via the serial port, the other computer will
understand that this is an `A'.
The important thing to observe in the ASCII table is the contiguous
arrangement of the uppercase alphabets (41-5A), the lowercase alphabets
(61-7A), and the numbers (30-39). This helps in certain operations with
ASCII, for example converting the case of characters by adding or subtracting
0x20 from it. It also helps in converting a digit into its ASCII representation
by adding 0x30 to it.
6.2. DISPLAY MEMORY FORMATION
We will explore the working of the display with ASCII codes, since it is our
immediately accessible hardware. When 0x40 is sent to the VGA card, it will
turn pixels on and off in such a way that a visual representation of `A'
appears on the screen. It has no reality, just an interpretation. In later
chapters we will program the VGA controller to display a new shape when
the ASCII of `A' is received by it.
The video device is seen by the computer as a memory area containing the
ASCII codes that are currently displayed on the screen and a set of I/O ports
controlling things like the resolution, the cursor height, and the cursor
position. The VGA memory is seen by the computer just like its own memory.
There is no difference; rather the computer doesn't differentiate, as it is
accessible on the same bus as the system memory. Therefore if that
appropriate block of the screen is cleared, the screen will be cleared. If the
ASCII of `A' is placed somewhere in that block, the shape of `A' will appear on
the screen at a corresponding place.
This correspondence must be defined as the memory is a single
dimensional space while the screen is two dimensional having 80 rows and
25 columns. The memory is linearly mapped on this two dimensional space,
just like a two dimensional is mapped in linear memory. There is one word
per character in which a byte is needed for the ASCII code and the other byte
is used for the character's attributes discussed later. Now the first 80 words
will correspond to the first row of the screen and the next 80 words will
correspond to the next row. By making the memory on the video controller
accessible to the processor via the system bus, the processor is now in
control of what is displayed on the screen.
The three important things that we discussed are.
 One screen location corresponds to a word in the video memory
 The video controller memory is accessible to the processor like its
own memory.
 ASCII code of a character placed at a cell in the VGA memory will
cause the corresponding ASCII shape to be displayed on the
corresponding screen location.
Display Memory Base Address
The memory at which the video controller's memory is mapped must be a
standard, so that the program can be written in a video card independent
manner. Otherwise if different vendors map their video memory at different
places in the address space, as was the problem in the start, writing software
was a headache. BIOS vendors had a problem of dealing with various card
vendors. The IBM PC text mode color display is now fixed so that system
software can work uniformly. It was fixed at the physical memory location of
B8000. The first byte at this location contains the ASCII for the character
displayed at the top left of the video screen. Dropping the zero we can load
the rest in a segment register to access the video memory. If we do something
in this memory, the effect can be seen on the screen. For example we can
72
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
write a virus that makes any character we write drop to the bottom of the
screen.
Attribute Byte
The second byte in the word designated for one screen location holds the
foreground and background colors for the character. This is called its video
attribute. So the pair of the ASCII code in one byte and the attribute in the
second byte makes the word that corresponds to one location on the screen.
The lower address contains the code while the higher one contains the
attribute. The attribute byte as detailed below has the RGB for the
foreground and the background. It has an intensity bit for the foreground
color as well thus making 16 possible colors of the foreground and 8 possible
colors for the background. When bit 7 is set the character keeps on blinking
on the screen. This bit has some more interpretations like background
intensity that has to be activated in the video controller through its I/O
ports.
7
6
5
4
3
2
1
0
7
­
Blinking of foreground character
6
­
Red component of background color
5
­
Green component of background color
4
­
Blue component of background color
3
­
Intensity component of foreground color
2
­
Red component of foreground color
1
­
Green component of foreground color
0
­
Blue component of foreground color
Display Examples
Both DS and ES can be used to access the video memory. However we
commonly keep DS for accessing our data, and load ES with the segment of
video memory. Loading a segment register with an immediate operand is not
allowed in the 8088 architecture. We therefore load the segment register via a
general purpose register. Other methods are loading from a memory location
and a combination of push and pop.
mov
ax, 0xb800
mov
es, ax
This operation has opened a window to the video memory. Now the
following instruction will print an `A' on the top left of the screen in white
color on black background.
mov
word [es:0], 0x0741
The segment override is used since ES is pointing to the video memory.
Since the first word is written to, the character will appear at the top left of
the screen. The 41 that goes in the lower byte is the ASCII code for `A'. The
07 that goes in the higher byte is the attribute with I=0, R=1, G=1, B=1 for
the foreground, meaning white color in low intensity and R=0, G=0, B=0 for
the background meaning black color and the most significant bit cleared so
that there is no blinking. Now consider the following instruction.
mov
word [es:160], 0x1230
This is displayed 80 words after the start and there are 80 characters in
one screen row. Therefore this is displayed on the first column of the second
line. The ASCII code used is 30, which represents a `0' while the attribute
byte is 12 meaning green color on black background.
We take our first example to clear the screen.
Example 6.1
73
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
01
; clear the screen
02
[org 0x0100]
03
mov  ax, 0xb800
; load video base in ax
04
mov  es, ax
; point es to video base
05
mov  di, 0
; point di to top left column
06
07
nextchar:
mov
word [es:di], 0x0720
; clear next char on screen
08
add
di, 2
;
move to next screen location
09
cmp
di, 4000
;
has the whole screen cleared
10
jne
nextchar
;
if no clear next position
11
12
mov
ax, 0x4c00
; terminate program
13
int
0x21
The code for space is 20 while 07 is the normal attribute of low
07
intensity white on black with no blinking. Even to clear the screen or
put a blank on a location there is a numeric code.
08
DI is incremented twice since each screen location corresponds to
two byte in video memory.
09
DI is compared with 80*25*2=4000. The last word location that
corresponds to the screen is 3998.
Inside the debugger the operation of clearing the screen cannot be
observed since the debugger overwrites whatever is displayed on the screen.
Directly executing the COM file from the command prompt*, we can see that
the screen is cleared. The command prompt that reappeared is printed after
the termination of our application. This is the first application that can be
directly executed to see some output on the screen.
6.3. HELLO WORLD IN ASSEMBLY LANGUAGE
To declare a character in assembly language, we store its ASCII code in a
byte. The assembler provides us with another syntax that doesn't forces us to
remember the ASCII code. The assembler also provides a syntax that
simplifies declaration of consecutive characters, usually called a string. The
three ways used below are identical in their meaning.
db
0x61, 0x61, 0x63
db
'a', 'b', 'c'
db
'abc'
When characters are stored in any high level or low level language the
actual thing stored in a byte is their ASCII code. The only thing the language
helps in is a simplified declaration.
Traditionally the first program in higher level languages is to print "hello
world" on the screen. However due to the highly granular nature of assembly
language, we are only now able to write it in assembly language. In writing
this program, we make a generic routine that can print any string on the
screen.
Example 6.2
01
; hello world in assembly
02
[org 0x0100]
03
jmp  start
04
05
message:
db
'hello world'
; string to be printed
06
length:
dw
11
; length of the string
07
08
; subroutine to clear the screen
09
clrscr:
push es
10
push ax
11
push di
Remember that if this example is run in a DOS window on some newer
*
operating systems, a full screen DOS application must be run before this
program so that screen access is enabled.
74
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
12
13
mov
ax, 0xb800
14
mov
es, ax
; point es to video base
15
mov
di, 0
; point di to top left column
16
17
nextloc:
mov
word [es:di], 0x0720
; clear next char on screen
18
add
di, 2
;
move to next screen location
19
cmp
di, 4000
;
has the whole screen cleared
20
jne
nextloc
;
if no clear next position
21
22
pop
di
23
pop
ax
24
pop
es
25
ret
26
27
; subroutine to print a string at top left of screen
28
; takes address of string and its length as parameters
29
printstr:
push bp
30
mov  bp, sp
31
push es
32
push ax
33
push cx
34
push si
35
push di
36
37
mov
ax,
0xb800
38
mov
es,
ax
;
point es to video base
39
mov
di,
0
;
point di to top left column
40
mov
si,
[bp+6]
;
point si to string
41
mov
cx,
[bp+4]
;
load length of string in cx
42
mov
ah,
0x07
;
normal attribute fixed in al
43
44
nextchar:
mov
al, [si]
;
load next char of string
45
mov
[es:di], ax
;
show this char on screen
46
add
di, 2
;
move to next screen location
47
add
si, 1
;
move to next char in string
48
loop
nextchar
;
repeat the operation cx times
49
50
pop
di
51
pop
si
52
pop
cx
53
pop
ax
54
pop
es
55
pop
bp
56
ret
4
57
58
start:
call clrscr
; call the clrscr subroutine
59
60
mov
ax, message
61
push
ax
; push address of message
62
push
word [length]
; push message length
63
call
printstr
; call the printstr subroutine
64
65
mov
ax, 0x4c00
; terminate program
66
int
0x21
The string definition syntax discussed above is used to declare a
05-06
string "hello world" of 11 bytes and the length is stored in a separate
variable.
09-25
The code to clear the screen from the last example is written in the
form of a subroutine. Since the subroutine had no parameters, only
modified registers are saved and restored from the stack.
29-35
The standard subroutine format with parameters received via stack
and all registers saved and restored is used.
37-42
ES is initialized to point to the video memory via the AX register.
Two pointer registers are used; SI to point to the string and DI to
point to the top left location of the screen. CX is loaded with the
length of the string. Normal attribute of low intensity white on black
with no blinking is loaded in the AH register.
44-45
The next character from the string is loaded into AL. Now AH holds
the attribute and AL the ASCII code of the character. This pair is
75
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
written on the video memory using DI with the segment override
46-47
prefix for ES to access the video memory segment.
The string pointer is incremented by one while the video memory
pointer is incremented by two since one char corresponds to a word
48
on the screen.
The loop instruction used is equivalent to a combination of "dec cx"
50-56
and "jnz nextchar." The loop is executed CX times.
The registers pushed on the stack are recovered in opposite order
and the "ret 4" instruction removes the two parameters placed on
the stack.
62
Memory can be directly pushed on the stack.
When the program is executed, screen is cleared and the greetings is
displayed on the top left of the screen. This screen location and the attribute
used were hard coded in the program and can also be made variable. Then
we will be able to print anywhere on the screen.
6.4. NUMBER PRINTING IN ASSEMBLY
Another problem related to the display is printing numbers. Every high
level language allows some simple way to print numbers on the screen. As we
have seen, everything on the screen is a pair of ASCII code and its attribute
and a number is a raw binary number and not a collection of ASCII codes.
For example a 10 is stored as a 10 and not as the ASCII code of 1 followed by
the ASCII code of 0. If this 10 is stored in a screen location, the output will
be meaningless, as the character associate to ASCII code 10 will be shown on
the screen. So there is a process that converts a number in its ASCII
representation. This process works for any number in any base. We will
discuss our examples with respect to the decimal base and later observe the
effect of changing to different bases.
Number Printing Algorithm
The key idea is to divide the number by the base number, 10 in the case of
decimal. The remainder can be from 0-9 and is the right most digit of the
original number. The remaining digits fall in the quotient. The remainder can
be easily converted into its ASCII equivalent and printed on the screen. The
other digits can be printed in a similar manner by dividing the quotient again
by 10 to separate the next digit and so on.
However the problem with this approach is that the first digit printed is the
right most one. For example 253 will be printed as 352. The remainder after
first division was 3, after second division was 5 and after the third division
was 2. We have to somehow correct the order so that the actual number 253
is displayed, and the trick is to use the stack since the stack is a Last In
First Out structure so if 3, 5, and 2 are pushed on it, 2, 5, and 3 will come
out in this order. The steps of our algorithm are outlined below.
 Divide the number by base (10 in case of decimal)
 The remainder is its right most digit
 Convert the digit to its ASCII representation (Add 0x30 to the
remainder in case of decimal)
 Save this digit on stack
 If the quotient is non-zero repeat the whole process to get the next
digit, otherwise stop
 Pop digits one by one and print on screen left to right
DIV Instruction
The division used in the process is integer division and not floating point
division. Integer division gives an integer quotient and an integer remainder.
A division algorithm is now needed. Fortunately or unfortunately there is a
76
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
DIV instruction available in the 8088 processor. There are two forms of the
DIV instruction. The first form divides a 32bit number in DX:AX by its 16bit
operand and stores the 16bit quotient in AX and the 16bit remainder in DX.
The second form divides a 16bit number in AX by its 8bit operand and stores
the 8bit quotient in AL and the 8bit remainder in AH. For example "DIV BL"
has an 8bit operand, so the implied dividend is 16bit and is stored in the AX
register and "DIV BX" has a 16bit operand, so the implied dividend is 32bit
and is therefore stored in the concatenation of the DX and AX registers. The
higher word is stored in DX and the lower word in AX.
If a large number is divided by a very small number it is possible that the
quotient is larger than the space provided for it in the implied destination. In
this case an interrupt is automatically generated and the program is usually
terminated as a result. This is called a divide overflow error; just like the
calculator shows an ­E­ when the result cannot be displayed. This interrupt
will be discussed later in the discussion of interrupts.
DIV (divide) performs an unsigned division of the accumulator (and its
extension) by the source operand. If the source operand is a byte, it is
divided into the two-byte dividend assumed to be in registers AL and AH. The
byte quotient is returned in AL, and the byte remainder is returned in AH. If
the source operand is a word, it is divided into the two-word dividend in
registers AX and DX. The word quotient is returned in AX, and the word
remainder is returned in DX. If the quotient exceeds the capacity of its
destination register (FF for byte source, FFFF for word source), as when
division by zero is attempted, a type 0 interrupt is generated, and the
quotient and remainder are undefined.
Number Printing Example
The next example introduces a subroutine that can print a number
received as its only argument at the top left of the screen using the algorithm
just discussed.
Example 6.3
001
; number printing algorithm
002
[org 0x0100]
003
jmp  start
004
005-022
;;;;; COPY LINES 008-025 FROM EXAMPLE 6.2 (clrscr) ;;;;;
023
024
; subroutine to print a number at top left of screen
025
; takes the number to be printed as its parameter
026
printnum:
push bp
027
mov  bp, sp
028
push es
029
push ax
030
push bx
031
push cx
032
push dx
033
push di
034
035
mov
ax,
0xb800
036
mov
es,
ax
;
point es to video base
037
mov
ax,
[bp+4]
;
load number in ax
038
mov
bx,
10
;
use base 10 for division
039
mov
cx,
0
;
initialize count of digits
040
041
nextdigit:
mov
dx, 0
;
zero upper half of dividend
042
div
bx
;
divide by 10
043
add
dl, 0x30
;
convert digit into ascii value
044
push
dx
;
save ascii value on stack
045
inc
cx
;
increment count of values
046
cmp
ax, 0
;
is the quotient zero
047
jnz
nextdigit
;
if no divide it again
048
049
mov
di, 0
; point di to top left column
050
77
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
051
nextpos:
pop  dx
;
remove a digit from the stack
052
mov  dh, 0x07
;
use normal attribute
053
mov [es:di], dx
;
print char on screen
054
add  di, 2
;
move to next screen location
055
loop nextpos
;
repeat for all digits on stack
056
057
pop
di
058
pop
dx
059
pop
cx
060
pop
bx
061
pop
ax
062
pop
es
063
pop
bp
064
ret
2
065
066
start:
call
clrscr
; call the clrscr subroutine
067
068
mov ax, 4529
069
push ax
; place number on stack
070
call printnum
; call the printnum subroutine
071
072
mov ax, 0x4c00
; terminate program
073
int 0x21
The registers are saved as an essential practice. The only parameter
026-033
received is the number to be printed.
ES is initialized to video memory. AX holds the number to be
035-039
printed. BX is the desired base, and can be loaded from a parameter.
CX holds the number of digits pushed on the stack. This count is
initialized to zero, incremented with every digit pushed and is used
when the digits are popped one by one.
DX must be zeroed as our dividend is in AX and we want a 32bit
041-042
division. After the division AX holds the quotient and DX holds the
remainder. Actually the remainder is only in DL since the remainder
can be from 0 to 9.
The remainder is converted into its ASCII representation and saved
043-045
on the stack. The count of digits on the stack is incremented as well.
If the quotient is zero, all digits have been saved on the stack and if
046-047
it is non-zero, we have to repeat the process to print the next digit.
DI is initialized to point to the top left of the screen, called the cursor
049
home. If the screen location is to become a parameter, the value
loaded in DI will change.
A digit is popped off the stack, the attribute byte is appended to it
051-053
and it is displayed on the screen.
The next screen location is two bytes ahead so DI is incremented by
054-055
two. The process is repeated CX times which holds the number of
digits pushed on the stack.
We pop the registers pushed and "ret 2" to discard the only
057-064
parameter on the stack.
The main program clears the screen and calls the printnum
066-070
subroutine to print 4529 on the top left of the screen.
When the program is executed 4529 is printed on the top left of the screen.
This algorithm is versatile in that the base number can be changed and the
printing will be in the desired base. For example if "mov bx, 10" is changed to
"mov bx, 2" the output will be in binary as 001000110110001. Similarly
changing it to "mov bx, 8" outputs the number in octal as 10661. Printing it
in hexadecimal is a bit tricky, as the ASCII codes for A-F do not consecutively
start after the codes for 0-9. Inside the debugger observe the working of the
algorithm is just as described in the above illustration. The digits are
78
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
separated one by one and saved on the stack. From bottom to top, the stack
holds 0034, 0035, 0032, and 0039 after the first loop is completed. The next
loop pops them one by one and routes them to the screen.
6.5. SCREEN LOCATION CALCULATION
Until now our algorithms used a fixed attribute and displayed at a fixed
screen location. We will change that to use any position on the screen and
any attribute. For mapping from the two dimensional coordinate system of
the screen to the one dimensional memory, we need to multiply the row
number by 80 since there are 80 columns per row and add the column
number to it and again multiply by two since there are 2 bytes for each
character.
For this purpose the multiplication routine written previously can be used.
However we introduce an instruction of the 8088 microprocessor at this time
that can multiply 8bit or 16bit numbers.
MUL Instruction
MUL (multiply) performs an unsigned multiplication of the source operand
and the accumulator. If the source operand is a byte, then it is multiplied by
register AL and the double-length result is returned in AH and AL. If the
source operand is a word, then it is multiplied by register AX, and the
double-length result is returned in registers DX and AX.
String Printing at Desired Location
We modify the string printing program to take the x-position, the y-
position, and the attribute as parameters. The desired location on the screen
can be calculated with the following formulae.
location = ( hypos * 80 + epos ) * 2
Example 6.4
01
; hello world at desired screen location
02
[org 0x0100]
03
jmp  start
04
05
message:
db
'hello world'
; string to be printed
06
length:
dw
11
; length of the string
07
08-25
;;;;; COPY LINES 008-025 FROM EXAMPLE 6.2 (clrscr) ;;;;;
26
27
; subroutine to print a string at top left of screen
28
; takes x position, y position, string attribute, address of string
29
; and its length as parameters
30
printstr:
push bp
31
mov  bp, sp
32
push es
33
push ax
34
push cx
35
push si
36
push di
37
38
mov
ax, 0xb800
39
mov
es, ax
; point es to video base
40
mov
al, 80
; load al with columns per row
41
mull
byte [bp+10]
; multiply with y position
42
add
ax, [bp+12]
; add x position
43
shl
ax, 1
; turn into byte offset
44
mov
dial
; point di to required location
45
mov
si, [bp+6]
; point si to string
46
mov
cx, [bp+4]
; load length of string in cx
47
mov
ah, [bp+8]
; load attribute in ah
48
49
nextchar:
mov
al, [si]
; load next char of string
50
mov
[es:di], ax
; show this char on screen
51
add
di, 2
; move to next screen location
79
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
52
add  si, 1
; move to next char in string
53
loop nextchar
; repeat the operation cx times
54
55
pop
di
56
pop
si
57
pop
cx
58
pop
ax
59
pop
es
60
pop
bp
61
ret
10
62
63
start:
call clrscr
; call the clrscr subroutine
64
65
mov
ax, 30
66
push
ax
; push x position
67
mov
ax, 20
68
push
ax
; push y position
69
mov
ax, 1
; blue on black attribute
70
push
ax
; push attribute
71
mov
ax, message
72
push
ax
; push address of message
73
push
word [length]
; push message length
74
call
printstr
; call the printstr subroutine
75
76
mov
ax, 0x4c00
; terminate program
77
int
0x21
Push and pop operations always operate on words; however data
41
can be read as a word or as a byte. For example we read the lower
byte of the parameter y-position in this case.
Shifting is used for multiplication by two, which should always be
43
the case when multiplication or division by a power of two is desired.
The subroutine had 5 parameters so "ret 10" is used.
61
The main program pushes 30 as x-position, 20 as y-position
65-74
meaning 30th column on 20th row. It pushes 1 as the attribute
meaning low intensity blue on black with no blinking.
When the program is executed hello world is displayed at the desired
screen location in the desired color. The x-position, y-position, and attribute
parameters can be changed and their effect be seen on the screen. The
important difference in this example is the use of MUL instruction and the
calculation of screen location given the x and y positions.
EXERCISES
1. Replace the following valid instruction with a single instruction that
has the same effect. Don't consider the effect on flags.
dec cx
jnz L3
2. Write an infinite loop that shows two asterisks moving from right and
left centers of the screen to the middle and then back. Use two empty
nested loops with large counters to introduce some delay so that the
movement is noticeable.
3. Write a function "printaddr" that takes two parameters, the segment
and offset parts of an address, via the stack. The function should
print the physical address corresponding to the segment offset pair
passed at the top left of the screen. The address should be printed in
hex and will therefore occupy exactly five columns. For example,
passing 5600 and 7800 as parameters should result in 5D800
printed at the top left of the screen.
4. Write code that treats an array of 500 bytes as one of 4000 bits and
for each blank position on the screen (i.e. space) sets the
corresponding bit to zero and the rest to one.
80
img
Computer Architecture & Assembly Language Programming
Course Code: CS401
CS401@vu.edu.pk
5. Write a function "drawrect" that takes four parameters via the stack.
The parameters are top, left, bottom, and right in this order. The
function should display a rectangle on the screen using the
characters + - and |.
81