Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
74
09-01.md
74
09-01.md
|
|
@ -19,46 +19,46 @@ mantle of the Earth and possibly all the way through to China. Many
|
|||
amusing cartoons were drawn to this effect.
|
||||
|
||||
Unfortunately, Barry was too busy drawing cartoons, or, alternatively,
|
||||
sleeping, to actually learn any math. In the long run, that didn’t turn
|
||||
sleeping, to actually learn any math. In the long run, that didn't turn
|
||||
out to be a handicap for Barry, who went on to become vice-president of
|
||||
sales for a ham-packing company, where presumably he was rarely called
|
||||
upon to derive the quadratic equation. Barry’s lack of scholarship
|
||||
upon to derive the quadratic equation. Barry's lack of scholarship
|
||||
caused some problems back then, though. On one memorable occasion, Barry
|
||||
was half-asleep, with his eyes open but unfocused and his chin balanced
|
||||
on his hand in the classic “if I fall asleep my head will fall off my
|
||||
hand and I’ll wake up” posture, when Mr. Bourgeis popped a killer
|
||||
on his hand in the classic "if I fall asleep my head will fall off my
|
||||
hand and I'll wake up" posture, when Mr. Bourgeis popped a killer
|
||||
problem:
|
||||
|
||||
“Barry, solve this for X, please.” On the blackboard lay the equation:
|
||||
"Barry, solve this for X, please." On the blackboard lay the equation:
|
||||
|
||||
X - 1 = 0
|
||||
|
||||
“Minus 1,” Barry said promptly.
|
||||
"Minus 1," Barry said promptly.
|
||||
|
||||
Mr. Bourgeis shook his head mournfully. “Try again.” Barry thought hard.
|
||||
Mr. Bourgeis shook his head mournfully. "Try again." Barry thought hard.
|
||||
He knew the fundamental rule that the answer to most mathematical
|
||||
questions is either 0, 1, infinity, -1, or minus infinity (do not apply
|
||||
this rule to balancing your checkbook, however); unfortunately, that
|
||||
gave him only a 25 percent chance of guessing right.
|
||||
|
||||
“One,” I whispered surreptitiously.
|
||||
"One," I whispered surreptitiously.
|
||||
|
||||
“Zero,” Barry announced. Mr. Bourgeis shook his head even more sadly.
|
||||
"Zero," Barry announced. Mr. Bourgeis shook his head even more sadly.
|
||||
|
||||
“One,” I whispered louder. Barry looked still more thoughtful—a bad
|
||||
sign—so I whispered “one” again, even louder. Barry looked so thoughtful
|
||||
"One," I whispered louder. Barry looked still more thoughtful—a bad
|
||||
sign—so I whispered "one" again, even louder. Barry looked so thoughtful
|
||||
that his eyes nearly rolled up into his head, and I realized that he was
|
||||
just doing his best to convince Mr. Bourgeis that Barry had solved this
|
||||
one by himself.
|
||||
|
||||
As Barry neared the climax of his stirring performance and opened his
|
||||
mouth to speak, Mr. Bourgeis looked at him with great concern. “Barry,
|
||||
can you hear me all right?”
|
||||
mouth to speak, Mr. Bourgeis looked at him with great concern. "Barry,
|
||||
can you hear me all right?"
|
||||
|
||||
“Yes, sir,” Barry replied. “Why?”
|
||||
"Yes, sir," Barry replied. "Why?"
|
||||
|
||||
“Well, I could hear the answer all the way up here. Surely you could
|
||||
hear it just one row away?”
|
||||
"Well, I could hear the answer all the way up here. Surely you could
|
||||
hear it just one row away?"
|
||||
|
||||
The class went wild. They might as well have sent us home early for all
|
||||
we accomplished the rest of the day.
|
||||
|
|
@ -66,15 +66,15 @@ we accomplished the rest of the day.
|
|||
I like to think I know more about performance programming than Barry
|
||||
knew about math. Nonetheless, I always welcome good ideas and comments,
|
||||
and many readers have sent me a slew of those over the years. So in this
|
||||
chapter, I think I’ll return the favor by devoting a chapter to reader
|
||||
chapter, I think I'll return the favor by devoting a chapter to reader
|
||||
feedback.
|
||||
|
||||
#### Another Look at LEA {#Heading3}
|
||||
|
||||
Several people have pointed out that while **LEA** is great for
|
||||
performing certain additions (see Chapter 6), it isn’t a perfect
|
||||
replacement for **ADD**. What’s the difference? **LEA**, an addressing
|
||||
instruction by trade, doesn’t affect the flags, while the arithmetic
|
||||
performing certain additions (see Chapter 6), it isn't a perfect
|
||||
replacement for **ADD**. What's the difference? **LEA**, an addressing
|
||||
instruction by trade, doesn't affect the flags, while the arithmetic
|
||||
**ADD** instruction most certainly does. This is no problem when
|
||||
performing additions that involve only quantities that fit in one
|
||||
machine word (32 bits in 386 protected mode, 16 bits otherwise), but it
|
||||
|
|
@ -89,7 +89,7 @@ could *not* be replaced
|
|||
LEA EAX,[EAX+EBX]
|
||||
ADC EDX,ECX
|
||||
|
||||
because **LEA** doesn’t affect the Carry flag.
|
||||
because **LEA** doesn't affect the Carry flag.
|
||||
|
||||
The no-carry characteristic of **LEA** becomes a distinct advantage when
|
||||
performing pointer arithmetic, however. For instance, the following code
|
||||
|
|
@ -103,43 +103,43 @@ variable to another such variable:
|
|||
|
||||
MOV EAX,[ESI] ;get the next element of one array
|
||||
ADC [EDI],EAX ;add it to the other array, with carry
|
||||
LEA ESI,[ESI+4] ;advance one array’s pointer
|
||||
LEA EDI,[EDI+4] ;advance the other array’s pointer
|
||||
LEA ESI,[ESI+4] ;advance one array's pointer
|
||||
LEA EDI,[EDI+4] ;advance the other array's pointer
|
||||
LOOP ADDLOOP
|
||||
|
||||
(Yes, I could use **LODSD** instead of **MOV/LEA**; I’m just
|
||||
(Yes, I could use **LODSD** instead of **MOV/LEA**; I'm just
|
||||
illustrating a point here. Besides, **LODS** is only 1 cycle faster than
|
||||
**MOV/LEA** on the 386, and is actually more than twice as slow on the
|
||||
486.) If we used **ADD** rather than **LEA** to advance the pointers,
|
||||
the carry from one **ADC** to the next would have to be preserved with
|
||||
either **PUSHF/POPF** or **LAHF/SAHF**. (Alternatively, we could use
|
||||
multiple **INC**s, since **INC** doesn’t affect the Carry flag.)
|
||||
multiple **INC**s, since **INC** doesn't affect the Carry flag.)
|
||||
|
||||
In short, **LEA** is indeed different from **ADD**. Sometimes it’s
|
||||
better. Sometimes not; that’s the nature of the various instruction
|
||||
In short, **LEA** is indeed different from **ADD**. Sometimes it's
|
||||
better. Sometimes not; that's the nature of the various instruction
|
||||
substitutions and optimizations that will occur to you over time.
|
||||
There’s no such thing as “best” instructions on the x86; it all depends
|
||||
on what you’re trying to do.
|
||||
There's no such thing as "best" instructions on the x86; it all depends
|
||||
on what you're trying to do.
|
||||
|
||||
But there sure are a lot of interesting options, aren’t there?
|
||||
But there sure are a lot of interesting options, aren't there?
|
||||
|
||||
#### The Kennedy Portfolio {#Heading4}
|
||||
|
||||
Reader John Kennedy regularly passes along intriguing assembly
|
||||
programming tricks, many of which I’ve never seen mentioned anywhere
|
||||
programming tricks, many of which I've never seen mentioned anywhere
|
||||
else. John likes to optimize for size, whereas I lean more toward speed,
|
||||
but many of his optimizations are good for both purposes. Here are a few
|
||||
of my favorites:
|
||||
|
||||
John’s code for setting AX to its absolute value is:
|
||||
John's code for setting AX to its absolute value is:
|
||||
|
||||
CWD
|
||||
XOR AX,DX
|
||||
SUB AX,DX
|
||||
|
||||
This does nothing when bit 15 of AX is 0 (that is, if AX is positive).
|
||||
When AX is negative, the code “nots” it and adds 1, which is exactly how
|
||||
you perform a two’s complement negate. For the case where AX is not
|
||||
When AX is negative, the code "nots" it and adds 1, which is exactly how
|
||||
you perform a two's complement negate. For the case where AX is not
|
||||
negative, this trick usually beats the stuffing out of the standard
|
||||
absolute value code:
|
||||
|
||||
|
|
@ -148,11 +148,11 @@ absolute value code:
|
|||
NEG AX ;yes,negate it
|
||||
IsPositive:
|
||||
|
||||
However, John’s code is slower on a 486; as you’re no doubt coming to
|
||||
realize (and as I’ll explain in Chapters 12 and 13), the 486 is an
|
||||
However, John's code is slower on a 486; as you're no doubt coming to
|
||||
realize (and as I'll explain in Chapters 12 and 13), the 486 is an
|
||||
optimization world unto itself.
|
||||
|
||||
Here’s how John copies a block of bytes from DS:SI to ES:DI, moving as
|
||||
Here's how John copies a block of bytes from DS:SI to ES:DI, moving as
|
||||
much data as possible a word at a time:
|
||||
|
||||
SHR CX,1 ;word count
|
||||
|
|
|
|||
Loading…
Reference in a new issue