Normal quotes

This commit is contained in:
James Gregory 2013-12-30 18:34:31 +11:00
commit 18011c595a
352 changed files with 6040 additions and 6040 deletions

View file

@ -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