# Category : Assembly Language Source Code

Archive : ASMTUT2.ZIP

Filename : CHAP0-2.DOC

xv

CHAPTER 0.2 - BASES 2 AND 16

I'm making the assumption that if you are along for the ride you

already know something about binary and hex numbers. This is a

review only.

BASE 2 AND BASE 16

Base 2 (binary) allows only 0s and 1s. Base 16 (hexadecimal)

allows 0 - 9, and then makes up the next six numbers by using the

letters A - F. A = 10, B=11, C=12, D=13, E=14 and F=15. You can

directly translate a hex number to a binary number and a binary

number to a hex number. A group of four digits in binary is the

same as a single digit in hex. We'll get to that in a moment.

The binary digits (BITS) are the powers of 2. The values of the

digits (in increasing order) are 1, 2, 4, 8, 16, 32, 64, 128, 256

and so on. 1 + 2 + 4 + 8 = 15, so the first four digits can

represent a hex number. This repeats itself every four binary

digits. Here are some numbers in binary, hex, and decimal

BINARY HEX DECIMAL

0100 4 4

1111 F 15

1010 A 10

0011 3 3

Let's go from binary to hex. Here's a binary number.

0110011010101101

To go from binary to hex, first divide the binary number up into

groups of four starting from the right.

0110 0110 1010 1101

Now simply change each group into a hex number.

0110 -> 4 + 2 -> 6

0110 -> 4 + 2 -> 6

1010 -> 8 + 2 -> A

1101 -> 8 + 4 + 1 -> D

and we have 66AD as the result. Similarly, to go from hex to

binary:

D39F

change each hex digit into a set of four binary digits:

D = 13 -> 8 + 4 + 1 -> 1101

______________________

The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson

The PC Assembler Tutor xvi

______________________

3 -> 2 + 1 -> 0011

9 -> 8 + 1 -> 1001

F = 15 -> 8+4+2+1 -> 1111

and then put them all together:

1101001110011111

Of course, having 16 digits strung out like that makes it totally

unreadable, so in this book, if we are talking about a binary

number, it will always be separated every 4 digits for

clarity.{1}

All computers operate on binary data, so why do we use hex

numbers? Take a test. Copy these two binary numbers:

1011 1000 0110 1010 1001 0101 0111 1010

0111 1100 0100 1100 0101 0110 1111 0011

Now copy these two hex numbers:

B86A957A

7C4C56F3

As you can see, you recognize hex numbers faster and you make

fewer mistakes in transcription with hex numbers.

ADDITION AND SUBTRACTION

The rules for binary addition are easy:

0 + 0 = 0

0 + 1 = 1

1 + 0 = 1

1 + 1 = 0 (carry 1 to the next digit left)

similarly for binary subtraction:

0 - 0 = 0

0 - 1 = 1 (borrow 1 from the next digit left)

1 - 0 = 1

1 - 1 = 0

On the 8086, you can have a 16 bit (binary digit) number

represent a number from 0 - 65535. 65535 + 1 = 0 (65536). For

binary numbers, the boundary is 65535/0. You count up or down

through that boundary. The 8086 is a mod 65536 machine. That

means the things that are equivalent to 35631 mod 65536 are:{2}

____________________

1. This will not be true of the actual assembler code, since

the assembler demands an unseparated number.

2. 35631 + 29905 = 65536. -29905 = 35631 (mod 65536)

Chapter 0.2 - Binary and Hex Numbers xvii

____________________________________

(3*65536 + 35631) (3*65536 - 29905)

(2*65536 + 35631) (2*65536 - 29905)

(1*65536 + 35631) (1*65536 - 29905)

( 0 + 35631) ( 0 - 29905)

(-1*65536 + 35631) (-1*65536 - 29905)

(-2*65536 + 35631) (-2*65536 - 29905)

(-3*65536 + 35631) (-3*65536 - 29905)

The unsigned number 35631 and the signed number -29905 look the

same. They ARE the same. In all addition, they will operate in

the same fashion. The unsigned number will use CF (the carry

flag) and the signed number will use OF (the overflow flag).

On all 16 bit computers, 0-32767 is positive and 32768 - 65535 is

negative. Here's 32767 and 32768.

32767 0111 1111 1111 1111

32768 1000 0000 0000 0000

32768 and all numbers above it have the left bit 1. 32767 and all

numbers below it have the left bit 0. This is how to tell the

sign of a signed number. If the left bit is 0 it's positive and

if the left bit is 1 it's negative.

TWO'S COMPLEMENT

In base 10 we had 10s complement to help us with negative

numbers. In base 2, we have 2s complememt.

0 = 65536 = 65535 + 1

so we have:

1 0000 0000 0000 0000 = 1111 1111 1111 1111 + 1

To get the negative of a number, we subtract:

-49 = 0 - 49 = 65536 - 49 = 65535 - 49 + 1

(65536) 1111 1111 1111 1111 + 1

(49) 0000 0000 0011 0001

result 1111 1111 1100 1110 + 1 -> 1111 1111 1100 1111 (-49)

; - - - - -

-21874

(65536) 1111 1111 1111 1111 + 1

(21874) 0101 0101 0101 0111

result 1010 1010 1010 1000 + 1 -> 1010 1010 1010 1001 (-21847)

; - - - - -

-11628

(65536) 1111 1111 1111 1111 + 1

(11628) 0010 1101 0110 1100

result 1101 0010 1001 0011 + 1 -> 1101 0010 1001 0100 (-11628)

; - - - - -

The PC Assembler Tutor xviii

______________________

-1764

(65536) 1111 1111 1111 1111 + 1

(1764) 0000 0110 1110 0100

result 1111 1001 0001 1011 + 1 -> 1111 1001 0001 1100 (-1764)

; - - - - -

Notice that since:

1 - 0 = 1

1 - 1 = 0

when you subtract from 1, you are simply switching the value of

the subtrahend (that's the number that you subtract).

1 -> 0

0 -> 1

1 becomes 0 and 0 becomes 1. You don't even have to think about

it. Just switch the 1s to 0s and switch the 0s to 1s, and then

add 1 at the end. Well do one more:

-348

(65536) 1111 1111 1111 1111 + 1

(348) 0000 0001 0101 1100

result 1111 1110 1010 0011 + 1 -> 1111 1110 1010 0100 (-348)

Now two more, this time without the crutch of having the top

number visible. Remember, even though you are subtracting, all

you really need to do is switch 1s to 0s and switch 0s to 1s, and

then add 1 at the end.

-658

(658) 0000 0010 1001 0010

result 1111 1101 0110 1101 + 1 -> 1111 1101 0110 1110 (-658)

; - - - - -

-31403

(34103) 0111 1010 0100 0111

result 1000 0101 1011 1000 + 1 -> 1000 0101 1011 1001 (-31403)

SIGN EXTENSION

If you want to use larger numbers, it is possible to use multiple

words to represent them.{3} The arithmetic will be done 16 bits

at a time, but by using the method described in Chapter 0.1, it

is possible to add and subtract numbers of any length. One normal

length is 32 bits. How do you convert a 16 bit to a 32 bit

number? If it is unsigned, simply put 0s to the left:

0100 1100 1010 0111 -> 0000 0000 0000 0000 0100 1100 1010 0111

____________________

3. On the 8086, a word is 16 bits.

Chapter 0.2 - Binary and Hex Numbers xix

____________________________________

What if it is a signed number? The first thing we need to know

about signed numbers is what is positive and what is negative.

Once again, for reasons of symmetry, we choose positive to be

from 0000 0000 0000 0000 0000 0000 0000 0000

to 0111 1111 1111 1111 1111 1111 1111 1111

(hex 00000000 to 7FFFFFFF)

and we choose negative to be

from 1000 0000 0000 0000 0000 0000 0000 0000

to 1111 1111 1111 1111 1111 1111 1111 1111

(hex 10000000 to FFFFFFFF).{4}

This longer number system cycles

from 1111 1111 1111 1111 1111 1111 1111 1111

to 0000 0000 0000 0000 0000 0000 0000 0000

(hex FFFFFFFF to 00000000).

Notice that by using binary numbers we are innundating ourselves

with 1s and 0s.

If it is a positive signed number, it is still no problem (recall

that in our 16 bit system, a positive number is between 0000 0000

0000 0000 and 0111 1111 1111 1111, a negative signed number is

between 1000 0000 0000 0000 and 1111 1111 1111 1111). Just put 0s

to the left. Here are some positive signed numbers and their

conversions:

(1974)

0000 0111 1011 0110 -> 0000 0000 0000 0000 0000 0111 1011 0110

(1)

0000 0000 0000 0001 -> 0000 0000 0000 0000 0000 0000 0000 0001

(3909)

0000 1111 0100 0101 -> 0000 0000 0000 0000 0000 1111 0100 0101

If it is a negative number, where did its representation come

from in our 16 bit system? -x -> 1111 1111 1111 1111 + 1 -x =

1111 1111 1111 1111 - x + 1. This time it won't be FFFFh + 1 but

FFFFFFFFh + 1. Let's have some examples. (Here we have 8 bits to

the group because there is not enough space on the line to

accomodate 4 bits to the group).

16 BIT SYSTEM 32 BIT SYSTEM

-1964

11111111 11111111 + 1 11111111 11111111 11111111 11111111 + 1

00000111 10101100 00000000 00000000 00000111 10101100

11111000 01010011 + 1 11111111 11111111 11111000 01010011 + 1

11111000 01010100 11111111 11111111 11111000 01010100

____________________

4. Once again, the sign will be decided by the left hand

digit. If it is 0 it is a positive number; if it is 1 it is a

negative number.

The PC Assembler Tutor xx

______________________

-2867

11111111 11111111 + 1 11111111 11111111 11111111 11111111 + 1

00001011 00110011 00000000 00000000 00001011 00110011

11110100 11001100 + 1 11111111 11111111 11110100 11001100 + 1

11110100 11001101 11111111 11111111 11110100 11001101

-182

11111111 11111111 + 1 11111111 11111111 11111111 11111111 + 1

00000000 10110110 00000000 00000000 00000000 10110110

11111111 01001001 + 1 11111111 11111111 11111111 01001001 + 1

11111111 01001010 11111111 11111111 11111111 01001010

As you can see, all you need to do to sign extend a negative

number is to put 1s to the left.

Can't those 1s on the left become 0s when we add that 1 at the

end? No. In order for that to happen, the right 16 bits must be

1111 1111 1111 1111. But that can only happen if the number to be

negated is 0:

1111 1111 1111 1111 1111 1111 1111 1111 + 1

-0000 0000 0000 0000

1111 1111 1111 1111 1111 1111 1111 1111 + 1 ->

0000 0000 0000 0000 0000 0000 0000 0000

In all other cases, adding 1 does not carry anything out of the

right 16 bits.

It is impossible to truncate one of these 32 bit numbers to a 16

bit number without making the results unreliable. Here are two

examples:

+1,687,451

00000000 00011001 10111111 10011011 -> 10111111 10011011 (-16485)

-3,524,830

11111111 11001010 00110111 00100010 -> 00110111 00100010 (+14114)

Truncating has changed both the sign and the absolute value of

the number.

xxi

CHAPTER 0.3 - LOGIC

Programs use numbers a lot. But they also ask questions that

require a yes/no answer. Is there an 8087 chip in the computer?

Is there a color monitor; how about a monochrome monitor? Is

there keyboard input waiting to be processed? Are you going to

get lucky on your date on Friday? Or, since you are a computer

programmer, are you going to have a date this month? Did the file

open correctly? Have we reached end of file?

In order to combine these logical questions to our heart's

content, we need a few operations: AND, OR, XOR (exclusive or),

and NOT.

AND

If we have two sentences "A" and "B", then ("A" AND "B") is true

if (and only if) both "A" and "B" are true. "It is raining and I

am wet" is true only if both "It is raining" and "I am wet" are

true. If one or both are false, then 'A and B' is false. A

shortcut for writing this is to use a truth table. A truth table

tells under what conditions an expression is true or false. All

we need to know is whether each component expression is true or

false. T stands for true, F for false.

"A" "B" "A" AND "B"

T T T

T F F

F T F

F F F

Notice that the truth table does NOT say anything about whether

the expression makes sense. The sentence:

"It's hot and I am sweating."

is a reasonable expression which may or may not be true. It will

be true if both "It is hot" and "I am sweating" are true. But the

sentence:

"The trees are green and Quito is the Capital of Ecuador."

is pure garbage. It does not satisfy our idea of what a sensible

expression should be, and should NEVER be evaluated by means of a

truth table. The warranty on a truth table is, if the expression

makes sense, then the truth table will tell you under what

conditions it is true or false. If the expression does not make

sense, then the truth table tells you nothing.

Fortunately, this problem really belongs to philisophical logic.

When you use logical operators in your program, there will be a

______________________

The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson

The PC Assembler Tutor xxii

______________________

well defined reason for each use. If you start doing screwy

things, your program probably won't run.

OR

There are two different types of OR alive and kicking in the

English language - the exclusive OR (A or B but not both) and the

inclusive OR (A or B or both).

A mother tells her child "You can have a piece of cake or a piece

of candy." Does this mean that he can have both if he wants? Of

course not. He can have one or the other, but not both. This is

XOR, the exclusive or. The truth table for this is:

"A" "B" "A" XOR "B"

T T F

T F T

F T T

F F F

'A XOR B' is true if exactly one of them is true. If they both

are true 'A XOR B' is false. If neither is true, 'A XOR B' is

false. Examples of XOR are:

1) We will either go to Italy or to Japan on our vacation.

2) I'll either have a tuna salad or a chef's salad.

3) He'll either buy a Lamborghini or a BMW.

Consider this sentence: "To go to Harvard, you need to have

connections or to be very smart." Do we want this to mean that if

you have connections but are very smart, you are automatically

excluded from going to Harvard? No. We want this to mean one or

the other or perhaps both. Sometimes you write this as 'and/or'

if you want to be absolutely clear. This is the inclusive OR. The

truth table for OR is:

"A" "B" "A" OR "B"

T T T

T F T

F T T

F F F

'A OR B' is true if one or both of them are true. If both are

false, then it is false. Examples of OR are:

1) They'll either go to Italy or to Austria on their

vacation.

2) I'll have either steak or shrimp at The Sizzler.

3) He'll buy either a paisley tie or a rep tie.

The three sentences for XOR and OR mimic each other on purpose.

In the English language, you know which type of OR is being used

by what is being talked about. You know intuitively which one

Chapter 0.3 - Logic xxiii

___________________

applies. If someone buys two different ties you are not suprised.

If someone buys two expensive cars at the same time you are quite

surprised.{1} With very few exceptions, if you confuse the two

you are doing it on purpose. If your father says "You can have

the car on Friday night or on Saturday night." and you don't

understand which OR applies, it's not his fault.

NOT

The final logical operation is NOT. The sentence: "It is not

raining." is false if it is raining, and true otherwise. The

truth table is:

"A" NOT "A"

T F

F T

This is self-explanatory.

Amazingly enough, this is all you need to know about logic to be

a quality programmer. Trying to make very complex combinations of

these logical operations may be fun for philosophy, but it is

death to a program. KISS is the operative word in programming.{2}

____________________

1. Especially if his job is working the cash register at

Sears.

2. Which, if you don't know, is Keep It Simple, Stupid.

xxiv

CHAPTER 0.4 - MEMORY

The basic unit of memory on 8086 machines is the byte.{1} This

means that in every memory cell we can store a number from 0 to

255. Each memory cell has an address. The first one in memory has

address 0, then address 1, then 2, then 3, etc.

The registers on the 8086 are one word (two bytes) long. This

means that any register can store and operate on a number from 0

to 65,535. (It also has some registers which can operate on bytes

and can store and operate on numbers from 0 to 255.)

Memory is physically external to the 8086. Registers are

physically internal to the 8086; they are actually on the chip.

One of the ways that we can access memory on the 8086 is by

putting the address of a memory cell in a register and then

telling the 8086 that we want to use the data at that memory

address.

Since each byte has its own address, and since we can't have a

number larger that 65,535 in any one register, it is impossible

to address more than 65,535 bytes with a single register. Back in

the dark ages, that might have been enough memory, but it sure

isn't enough nowdays.

Intel solved the problem by creating SEGMENTS. Each segment is

65,536 bytes long, going from address 0 to address 65,535.{2} You

tell the 8086 where you want to go in memory by telling it which

segment you are in and what the address is within that segment.

Segments are numbered from 0 to 65,535. That is, there are 65,536

of them.

As a design decision, Intel decided that a segment should start

every 16 bytes. This decision was made in the late 70's and is

cast in stone. On the 8086, a segment starts every 16 bytes. Here

is a list of some segments, with the segment number and the

segment starting address in both decimal and hex.

SEGMENT NUMBER STARTING ADDRESS

0d 0h 0d 00h

1d 1h 16d 10h

2d 2h 32d 20h

3d 3h 48d 30h

4d 4h 64d 40h

____________________

1. As it is on all computers.

2. The last segments are actually less that 65,535, as will be

explained later.

______________________

The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson

Chapter 0.4 - Memory xxv

____________________

200d C8h 3,200d C80h

21694d 54BEh 347,104d 54BE0h

51377d C8B1h 822,032d C8B10h

One thing you should note is that in hex, the segment number is

the same as the starting address, except that the starting

address has an extra 0 digit on the right.

These segments overlap. A new segment starts every 16 bytes, and

they are all 65,535 bytes long. This means that with the

exception of the first 16 bytes, any address in memory is in more

that one segment. Here are some addresses. The word "offset"

means the number of bytes from the beginning of the segment. (It

is possible for a memory cell to have an offset 0). The offset is

shown in both decimal (d) and hex (h):

memory address 55 (37h)

Seg # Offset Offset

0 55d 37h

1 39d 27h

2 23d 17h

3 7d 7h

Thus the address 55 is in 4 different segments, and can be

addressed relative to any one of them.

memory address 17,946 (461Ah)

Seg # Offset Offset

0 17,946d 461Ah

1 17,930d 460Ah

2 17,914d 45FAh

... ...

1120 26d 1Ah

1121 10d 0Ah

The address 17,946 is in 1122 different segments, and can be

addressed relative to any of them. Notice that as the segment

number goes up one segment, the offset address goes down 16 bytes

(10h).

Above the address 65,519, every memory cell can be addressed by

4,096 different segments.

Because of the way the addresses are generated on the 8086, the

maximum memory address possible is 1,048,575 (FFFFF hex.) This

means that the final segments are less than 65,536 bytes long. In

this table "Address" is the starting address of the segment. All

the following numbers are decimal:

Segment # Address Max Offset

65,535d 1,048,560d 15d

65,534d 1,048,544d 31d

65,533d 1,048,528d 47d

... ... ...

The PC Assembler Tutor xxvi

______________________

64,000d 1,024,000d 24,575d

Let's look at these same numbers in hex:

Segment # Address Max Offset

FFFFh FFFF0h Fh

FFFEh FFFE0h 1Fh

FFFDh FFFD0h 2Fh

... ... ...

FA00h FA000h 5FFFh

The maximum addressable number is FFFFFh, which is why these

segments are cut short. There are 4,095 segments at the top which

are less than 65,536 bytes long. Don't worry, though, because

this top section of memory belongs to the operating system, and

your programs will never be put there. It will never affect you.

Back in the late 70s, a million bytes of memory seemed like a

lot. In the 60s, large mainframe computers had only a

half-million bytes of memory. In the 70s memory was still

exhorbitantly expensive. Nowdays, however, you practically need a

megabyte just to blow your nose. But this segmentation system is

cast in stone, so there is no way to get more memory on the

8086.{3}

In the beginning, when we make a program, we will use one segment

for the machine code, one segment for permanant data, and one

segment for temporary data. If we need it, this gives us 196,608

bytes of usable memory right off the bat. As you will see by the

time we are finished, ALL memory is addressable - we just need to

do more work to get to it all.

All this talk about segments and offsets may have you concerned.

If you have to keep track of all these offsets, programming is

going to be very difficult.{4} Not to worry. It is the

assembler's job to keep track of the offsets of every variable

____________________

3. This megabyte rule is unalterable. EMS (extended memory) is

actually a memory swapping program. On the 28086 and 80386 you

can have more than one megabyte of memory but the program can

only access one megabyte. The program reserves a section of its

one megabyte for a transfer area. It then calls EMS which

transfers the data from this extended memory to the transfer

area. It is in effect a RAM disk. It is like using a hard disk

but is much faster. If Intel had bitten the bullet with the 80286

and said that a segment would start every 256 bytes instead of

every 16 bytes, we would have 16 megabytes of directly accessible

memory instead of 1 megabyte. Hindsight is such a wonderful

thing.

4. Remember, an offset is just how many bytes a memory cell is

from the beginning of the segment.

Chapter 0.4 - Memory xxvii

____________________

and every label in your program.{5}

Which segments your program uses is decided by the operating

system when it loads your program into memory. It puts some of

this information into the 8086. At the start of the program, you

put the rest of the information into the 8086, and then you can

forget about segments.

NUMBERS IN MEMORY

The largest number you can store in a single byte is 255. If you

are calculating the distance from the sun to Alpha Centauri in

inches, obviously one byte is not enough. Unfortunately, the 8086

can't really handle large numbers like that.{6} It can handle

numbers which are 16 bits (2 bytes) long. However, with

subprograms supplied with all compilers, we can handle large

numbers, though rather slowly if we don't use an 8087. All these

different programs need a standard way to write numbers in

memory, and this standard is supplied by Intel. The standard is :

(1) integers can be 1, 2, or 4 bytes long. This corresponds

to -128 to +127 , -32,768 to +32,767, and -2,147,483,648 to

+2,147,483,647.

(2) scientific floating point numbers which have an exponent

and can be very large. They come as 4 byte and 8 byte numbers.

We will not deal with them at all, but we need to know how

they are stored.

(3) Commercial or BCD numbers which occupy 1/2 byte per

digit. Since some of the 8086 instructions are concerned with

these we will cover them, but if you are not curious about

them, you can skip that section. The standard is a 10 byte

number.

Let's look at a number. For the rest of this section, all numbers

will be hex, and if a number is longer than one byte, we will

display it with a blank space between each byte. If it is a one

byte number - e.g. 3C, we know exactly where we are going to put

it. But what if a number is 4 bytes long - e.g. 2D F5 33 0A - and

we want to put it in memory starting at offset 264. We have two

choices:

2D F5 33 0A

Address Choice 1 Choice 2

267 2D 0A

266 F5 33

265 33 F5

____________________

5. As in other languages, a label is a name that marks a place

in the code. In BASIC, labels are actually numbers (such as 500

in the instruction GOTO 500). Labels are frowned on in Pascal and

C, but are the lifeblood of assembler language.

6. But fortunately, the 8087 can.

The PC Assembler Tutor xxviii

______________________

264 0A 2D

Neither choice is better than the other. Choice 1 puts the

right-most byte in low memory, choice 2 puts the right-most byte

in high memory.{7} The right-most byte is called the LEAST

SIGNIFICANT BYTE because it has the least effect on a number,

while the left-most byte is called the MOST SIGNIFICANT BYTE

because it has the most effect on a number. In fact, Intel picked

choice #1 for the 8086 (which has the least significant byte in

low memory), and Motorola picked choice #2 for the 68000 (which

has the most significant byte in low memory).

This is consistent for both the 8086 and the 8087: THE LEAST

SIGNIFICANT BYTE IS ALWAYS IN LOW MEMORY: EACH NUMBER IN MEMORY

STARTS WITH THE LEAST SIGNIFICANT BYTE. Remember that, and you'll

save yourself some trouble.

One problem you will run up against is that when we draw pictures

of memory, we often draw from left to right, that is:

ADDRESS 264 265 266 267

When we do that, things start looking wierd. For 2D F5 33 0A we

have:

ADDRESS 264 265 266 267

VALUE 0A 33 F5 2D

This is exactly backwards. Remember, memory doesn't go from left

to right, it goes UP from 0, and THE LEAST SIGNIFICANT BYTE IS

ALWAYS IN LOW MEMORY. You will certainly make some mistakes till

you get used to being consistent about this. The right hand digit

of a number is always in low memory. If you think of memory as

being VERTICAL:

1E A3 07 B5

Value Address

1E 4782

A3 4781

07 4780

B5 4779

rather than being LEFT TO RIGHT:

Address 4779 4780 4781 4782

Value B5 07 A3 1E

you will be much better off.

____________________

7. Low memory always means the low addresses and high memory

always means the high addresses.

xxix

CHAPTER 0.5 - STYLE

Finally, it is time to say a word about style. Assembler code is

by its nature difficult to read. It divides any concept into a

number of sequential steps. If you have the BASIC statement:

MINUTES = DAYS * 1440

You get the idea because you can scan the line to see what is

wanted. The assembler code for the above line is: {1}

mov ax, days

mov bx, 1440

mul bx

mov minutes, ax

In BASIC, the concept was imbedded in the expression. In

assembler it was lost. This means two things. First, you must be

religious about documenting every step. If you come back to

something two or three months later and you haven't documented

what you are doing, it may take you longer to figure out what you

did than it would to completely rewrite what you did.

Secondly, if you are a person who likes code like this:

x = (y + k) / (z - 4)

you are headed for big trouble. At the assembler level it is

CRITICAL that you give every variable a name that signifies

exactly what it is. If you are counting the number of correct

answers, then the variable should be:

correct_answers

not 'K'. If you are looking at the remainder from a division,

then the variable should be:

remainder

not 'R'. If you try to use short names like 'x', 'k' and 'y', I

will guarantee that for every minute you save by not having to

type in long variable names, you will lose 10 minutes by not

being able to figure out what is going on when you reread the

code. In this tutorial we will use multiple words connected by

underscores:

first_positive_prime

median_age

oldest_student

____________________

1. Don't worry about what this code does. You will learn soon

enough.

______________________

The PC Assembler Tutor - Copyright (C) 1989 Chuck Nelson

The PC Assembler Tutor xxx

______________________

The Microsoft assembler allows 31 significant characters in a

name. Even though there are several other characters allowed, we

will use only letters, the underscore, and numbers (where

appropriate):

approximation1

approximation2

approximation3

This should make your code similar to well written C or Pascal

code, and greatly increase the readability of the code.