Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
24
04-02.md
24
04-02.md
|
|
@ -9,12 +9,12 @@
|
|||
**Figure 4.2** *Internal data bus widths of the 8088.*
|
||||
|
||||
As shown in Figure 4.1, the 8-bit bus cycle-eater lies squarely on the
|
||||
8088’s external data bus. Technically, it might be more accurate to
|
||||
8088's external data bus. Technically, it might be more accurate to
|
||||
place this cycle-eater in the Bus Interface Unit, which breaks 16-bit
|
||||
memory accesses into paired 8-bit accesses, but it is really the limited
|
||||
width of the external data bus that constricts data flow into and out of
|
||||
the 8088. True, the original PC’s bus is also only 8 bits wide, but
|
||||
that’s just to match the 8088’s 8-bit bus; even if the PC’s bus were 16
|
||||
the 8088. True, the original PC's bus is also only 8 bits wide, but
|
||||
that's just to match the 8088's 8-bit bus; even if the PC's bus were 16
|
||||
bits wide, data could still pass into and out of the 8088 chip itself
|
||||
only 1 byte at a time.
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ doubleword from memory in two halves.
|
|||
|
||||
One obvious effect of the 8-bit bus cycle-eater is that word-sized
|
||||
accesses to memory operands on the 8088 take 4 cycles longer than
|
||||
byte-sized accesses. That’s why the official instruction timings
|
||||
byte-sized accesses. That's why the official instruction timings
|
||||
indicate that for code running on an 8088 an additional 4 cycles are
|
||||
required for every word-sized access to a memory operand. For instance,
|
||||
|
||||
|
|
@ -54,11 +54,11 @@ takes 4 cycles longer to read the word at address **MemVar** than
|
|||
mov al,byte ptr [MemVar]
|
||||
|
||||
takes to read the byte at address **MemVar.** (Actually, the difference
|
||||
between the two isn’t very likely to be exactly 4 cycles, for reasons
|
||||
between the two isn't very likely to be exactly 4 cycles, for reasons
|
||||
that will become clear once we discuss the prefetch queue and dynamic
|
||||
RAM refresh cycle-eaters later in this chapter.)
|
||||
|
||||
What’s more, in some cases one instruction can perform multiple
|
||||
What's more, in some cases one instruction can perform multiple
|
||||
word-sized accesses, incurring that 4-cycle penalty on each access. For
|
||||
example, adding a value to a word-sized memory variable requires two
|
||||
word-sized accesses—one to read the destination operand from memory
|
||||
|
|
@ -79,7 +79,7 @@ accesses x 4 cycles, or *524,280 cycles* to the 8-bit bus cycle-eater!
|
|||
In other words, one 8088 instruction (admittedly, an instruction that
|
||||
does a great deal) can take over one-tenth of a second longer on an 8088
|
||||
than on an 8086, simply because of the 8-bit bus. *One-tenth of a
|
||||
second!* That’s a phenomenally long time in computer terms; in one-tenth
|
||||
second!* That's a phenomenally long time in computer terms; in one-tenth
|
||||
of a second, the 8088 can perform more than 50,000 additions and
|
||||
subtractions.
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ The obvious implication of the 8-bit bus cycle-eater is that byte-sized
|
|||
memory variables should be used whenever possible. After all, the 8088
|
||||
performs *byte-sized* memory accesses just as quickly as the 8086. For
|
||||
instance, Listing 4.1, which uses a byte-sized memory variable as a loop
|
||||
counter, runs in 10.03 s per loop. That’s 20 percent faster than the
|
||||
counter, runs in 10.03 s per loop. That's 20 percent faster than the
|
||||
12.05 µs per loop execution time of Listing 4.2, which uses a word-sized
|
||||
counter. Why the difference in execution times? Simply because each
|
||||
word-sized **DEC** performs 4 byte-sized memory accesses (two to read
|
||||
|
|
@ -138,18 +138,18 @@ in all.
|
|||
jnz LoopTop
|
||||
call ZTimerOff
|
||||
|
||||
I’d like to make a brief aside concerning code optimization in the
|
||||
listings in this book. Throughout this book I’ve modeled the sample code
|
||||
I'd like to make a brief aside concerning code optimization in the
|
||||
listings in this book. Throughout this book I've modeled the sample code
|
||||
after working code so that the timing results are applicable to
|
||||
real-world programming. In Listings 4.1 and 4.2, for example, I could
|
||||
have shown a still greater advantage for byte-sized operands simply by
|
||||
performing 1,000 **DEC** instructions in a row, with no branching at
|
||||
all. However, **DEC** instructions don’t exist in a vacuum, so in the
|
||||
all. However, **DEC** instructions don't exist in a vacuum, so in the
|
||||
listings I used code that both decremented the counter and tested the
|
||||
result. The difference is that between decrementing a memory location
|
||||
(simply an instruction) and using a loop counter (a functional
|
||||
instruction sequence). If you come across code in this book that seems
|
||||
less than optimal, it’s simply due to my desire to provide code that’s
|
||||
less than optimal, it's simply due to my desire to provide code that's
|
||||
relevant to real programming problems. On the other hand, optimal code
|
||||
is an elusive thing indeed; by no means should you assume that the code
|
||||
in this book is ideal! Examine it, question it, and improve upon it, for
|
||||
|
|
|
|||
Loading…
Reference in a new issue