CSAPP 六个重要实验 lab0(预热乱暖场 \-0-/ )

CS : APP  && Lab 0

之前在网上找了一会关于这几个实验的资料,发现都没有.其实washington university的<CSE351: The Hardware/Software Interface> 的课程实验.

伟大而又乐于分享的高校.WU

我陆续更新把这五个实验(这个预热的lab0不算,太简单,C入门的级别,这里指lab1~lab5),贴出来分析学习.希望更多的人能够收益. 开源,分享.

--------------------------------------------------------------------实验要求--------------------------------------------------------------------

Editing, compiling, and running the code

Now that you have acquired the source file, open arrays.c in your favorite text editor. arrays.c file contains a number of TODOs, which you are expected to complete. Most have a proceeding line that says "Answer:",
which is where you should leave an answer to the question(s) posed in the TODO. One TODO requires you to write some code, which you should place immediately after the comment block that describes what to do.

The source file arrays.c won‘t do you any good by itself; you need a compiler (specifically the GNU C compiler) to compile it to an executable format. The GNU C compiler is available on attu, the instructional Linux machines, the CSE home VM (https://www.cs.washington.edu/lab/software/homeVMs/)
, and most popular variants of Linux, such as Ubuntu and Fedora. You‘re free to use whichever machine you like, although we will only provide support for attu, the instructional Linux machines, and the CSE home VM.

--------------------------------------------------------------------------------------------------------------------------------------------------------

lab0要求的arrays.c如下

/*
  CSE 351 Lab 0
  Lecture 2 and the first section meeting will help you
  if none of this makes sense yet.
*/

// These #includes tell the compiler to include the named
// header files, similar to imports in Java. The code for
// these is generally located under /usr/include/, such
// as /usr/include/assert.h. assert.h contains the
// declaration of the assert() function, stdio.h contains
// the declaration of the printf() function, and stdlib.h
// contains the declaration of the malloc() and free()
// functions, all of which are used in the code below.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

// Fill the given array with values. Note that C doesn't
// keep track of the length of arrays, so we have to
// specify it as an explicit parameter here, rather than
// looking it up from the array as in Java.
// Additionally, note that the type of the array parameter
// here is int*, a pointer to an int. We'll learn more
// about why int* is used here, but for now it is enough
// to understand that array is an array of ints.
void fillArray(int* array, int len) {
  printf("Filling an array at address %p with %d "
         "values\n", array, len);
  for (int i = 0; i < len; ++i) {
    array[i] = i * 3 + 2;
    // assert() verifies that the given condition is true
    // and exits the program otherwise. This is just a
    // "sanity check" to make sure that the line of code
    // above is doing what we intend.
    assert(array[i] == i * 3 + 2);
  }
  printf("Done!\n");
}

// Structs are blocks of memory composed of smaller parts,
// each of which has a name and is called a field.  The
// following struct definition has four int fields named
// a, b, c, and d.
// In this case, we use typedef to give structs of this
// type a name, FourInts, which can be used like we use
// other types such as int or char.
typedef struct {
  int a, b, c, d;
} FourInts;

// main() is the entry point of the program. It has two
// parameters: argc is the number of arguments that were
// passed on the command line; argv is an array of those
// arguments as strings.  (Strings in C are arrays of
// chars.)
int main(int argc, char* argv[]) {
  // Create a new array capable of storing 10 elements
  // and fill it with values using the function declared
  // above. Arrays declared in this manner are allocated on
  // the stack, and must generally have a size (10, here)
  // that is a constant (i.e., the size is known when
  // writing the program, not computed when running it).
  int array[10];
  // This is a block of memory big enough to store 10
  // ints.  The name "array" here actually refers to the
  // address of this block of memory.
  // array[0] is the first int in this block of
  // memory, array[1] is the second, and so on. C does
  // not track or check array lengths, so it is up to us
  // to know how many elements the array contains.
  //
  // TODO(1): What happens if the second argument is set
  // to 11 instead? How about 100? 1000? Make sure to set
  // the second argument back to 10 when you are done
  // testing.
  // Answer:
  fillArray(array, 10);

  int value;
  // In C, we can take the address of something using the
  // & operator. &value is of the type int*, meaning that
  // it is a pointer to an integer (as it stores the
  // address in memory of where the actual int is located).
  //
  // TODO(2): We can actually use the address of the value
  // declared here as if it were an array of a single
  // element; why is this possible?
  // Answer:
  fillArray(&value, 1);
  // fillArray should set value to 0 * 3 + 2 = 2.
  assert(value == 2);

  // The following creates an instance of FourInts on the
  // stack. FourInts is really just an array of four ints,
  // although we can refer to the ints stored in it by
  // name as well.
  FourInts four_ints;
  // Set the first int to have a value of 0 and verify
  // that the value changed.
  four_ints.a = 0;
  assert(four_ints.a == 0);

  // Depending on whether or not you like to live
  // dangerously, the following is either exciting or
  // terrifying. Though &four_ints is of type FourInts*
  // (as in a pointer to a FourInts struct), we can
  // use a cast to pretend that it is actually an array
  // of integers instead.  It's all just memory after all.
  // The "(int*)" tells the C compiler that we want to treat
  // that address "&four_ints" as an address to an int (in
  // this case the start of an array) rather than a
  // FourInts struct.
  fillArray((int*) &four_ints, 4);
  // We can confirm that fillArray updated the values
  // in the FourInts struct:
  assert(four_ints.a == 2);
  assert(four_ints.b == 5);
  assert(four_ints.c == 8);
  assert(four_ints.d == 11);

  // In the case that the size of an array is not known
  // until runtime, the malloc() function can be used to
  // allocate memory dynamically. Memory that is
  // allocated dynamically is stored on the heap, which
  // is separate from the stack. We'll talk about all these
  // regions of memory later in the course.  C is unlike Java,
  // however, in that dynamically-allocated memory must
  // be freed explicitly when the program is done using
  // it via the free() function. malloc() takes a single
  // argument, which is the number of bytes to allocate,
  // and returns the address of a fresh memory object
  // whose size is the given argument.
  // sizeof(int) gives the size of an int in bytes
  // (which is four), so sizeof(int) * 5 is 20.
  int* heap_array = (int*) malloc(sizeof(int) * 5);
  fillArray(heap_array, 5);
  // Now that we have finished with the heap-allocated
  // array, free() the memory associated with it.
  //
  // TODO(3): What happens if we remove the free()
  // statement below? Try running "valgrind ./arrays"
  // after compiling the program both with and without
  // it. valgrind is a tool for analyzing how programs
  // use memory, which is often invaluable for C and
  // C++ programming.
  // Answer:
  free(heap_array);

  // TODO(4): Now it's your turn to write some code.
  // Using malloc(), allocate a FourInts struct
  // dynamically (on the heap) and use fillArray to
  // populate it with values. The sizeof function can
  // be used on any data type. Make sure to free the
  // memory when you are done, and use the valgrind
  // tool mentioned above to check that there aren't
  // any errors. As a "sanity check," add four assert
  // statements to verify that the a, b, c, and d
  // fields of the FourInts struct are set to what
  // you would expect. (Hint, since you will have a
  // pointer to a FourInts struct you will need to
  // use the -> operator to access fields of a
  // FourInts* variable instead of the . operator
  // we used on the FourInts above.  ptr->a is
  // equivalent to (*ptr).a .  Note the difference
  // between FourInts and FourInts*.)
  return 0;
}

Jason Leaster 给出的解答(由于是本人自己给出的解,如有錯漏望慷慨指出):

/*
  CSE 351 Lab 0
  Lecture 2 and the first section meeting will help you
  if none of this makes sense yet.
*/

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

void fillArray(int* array, int len) {
  printf("Filling an array at address %p with %d "
         "values\n", array, len);
  for (int i = 0; i < len; ++i) {
    array[i] = i * 3 + 2;
    assert(array[i] == i * 3 + 2);
  }
  printf("Done!\n");
}

typedef struct {
  int a, b, c, d;
} FourInts;

int main(int argc, char* argv[]) {

  int array[10];

  // TODO(1): What happens if the second argument is set
  // to 11 instead? How about 100? 1000? Make sure to set
  // the second argument back to 10 when you are done
  // testing.

 /* Answer by Jason Leaster:
			This problem's purpose is to guide
	you to understand what is "stack". You may have to
	understand code on running-time at level of assembly.
	Here is my notes,
	-------------------------------------------------------
	http://blog.csdn.net/cinmyheart/article/details/24483461 

	http://blog.csdn.net/cinmyheart/article/details/39142471
	-------------------------------------------------------
	finish it and it will help you to get a background to
	understand this problem.

	If you set the second argument to "11" instead, the
	program work well in 64-bits Ubuntu. But if you set
	the second parameter bigger than 12 (like 13,18,1000),
	you would destroy the %rbp register's value in this
	program and you will see "core dump" when you run it.

  */
  fillArray(array, 10);

  int value;
  //
  // TODO(2): We can actually use the address of the value
  // declared here as if it were an array of a single
  // element; why is this possible?

  /* Answer by Jason Leaster:         

			For this problem, what I want to
	say is that "God save me, it just a feature of C".
  */
  fillArray(&value, 1);
  assert(value == 2);

  FourInts four_ints;
  four_ints.a = 0;
  assert(four_ints.a == 0);

  fillArray((int*) &four_ints, 4);
  assert(four_ints.a == 2);
  assert(four_ints.b == 5);
  assert(four_ints.c == 8);
  assert(four_ints.d == 11);

  int* heap_array = (int*) malloc(sizeof(int) * 5);
  fillArray(heap_array, 5);

  // TODO(3): What happens if we remove the free()
  // statement below? Try running "valgrind ./arrays"
  // after compiling the program both with and without
  // it. valgrind is a tool for analyzing how programs
  // use memory, which is often invaluable for C and
  // C++ programming.

  /* Answer by Jason Leaster:
			I will show a figure which is
	in my blog to describe what would happen, if
	we remove the free() statement below.
  */
  free(heap_array);

  // TODO(4): Now it's your turn to write some code.
  // Using malloc(), allocate a FourInts struct
  // dynamically (on the heap) and use fillArray to
  // populate it with values. The sizeof function can
  // be used on any data type. Make sure to free the
  // memory when you are done, and use the valgrind
  // tool mentioned above to check that there aren't
  // any errors. As a "sanity check," add four assert
  // statements to verify that the a, b, c, and d
  // fields of the FourInts struct are set to what
  // you would expect. (Hint, since you will have a
  // pointer to a FourInts struct you will need to
  // use the -> operator to access fields of a
  // FourInts* variable instead of the . operator
  // we used on the FourInts above.  ptr->a is
  // equivalent to (*ptr).a .  Note the difference
  // between FourInts and FourInts*.)

  /*
	Answer for TODO(4) by jasonleaster:

		It is too easy for a C programmer.
	I have to say sorry about someone who can't
	use malloc() and free() correctly.

	I don't want to demo for someone how to use
	free() and malloc().

				Nice trip.	:)
  */
  return 0;
}

valgrind 倒是个好东西~

时间: 2024-08-05 08:03:30

CSAPP 六个重要实验 lab0(预热乱暖场 \-0-/ )的相关文章

CSAPP 六个重要实验 lab4

CSAPP && lab4 实验材料: http://download.csdn.net/detail/u011368821/7926305 实验指导书: http://download.csdn.net/detail/u011368821/7926323 实验环境: Linux 3.13.11 Ubuntu 14.0 Part I: An Experiment in C and Java Q&A Answer these questions: 1.  What are the s

CSAPP 六个重要实验 lab5

CSAPP  && lab5 实验指导书: http://download.csdn.net/detail/u011368821/7951657 实验材料: http://download.csdn.net/detail/u011368821/8019293 搞定这个实验还是要看一下以前的笔记,再复习一下block的组织方式,只看link里面第11节,动态内存分配的部分就可以了 http://blog.csdn.net/cinmyheart/article/details/38136375

CSAPP 六个重要实验 lab2

CSAPP  &&  lab2 哈哈~ 不愧是"美国进口的六级炸弹"!爽歪歪的"升级打怪" 我把实验材料都上传到下面这个link了,0分下载(良心啊~) http://download.csdn.net/detail/u011368821/7892649 再一个实验指导说明供大家下载: http://download.csdn.net/detail/u011368821/7892677 对于Phase_1的分析: 0000000000400ef0 &

CSAPP 六个重要实验 lab1

CSAPP && lab1 --------------------------------------------------------------------实验要求-------------------------------------------------------------------- The Bit Puzzles This section describes the puzzles that you will be solving in bits.c. More

CSAPP 六个重要实验 lab3

CSAPP && lab3 level2 & leve3未完,待更新! : ) In this lab, you will gain firsthand experience with one of the methods commonly used to exploit security weaknesses in operating systems and network servers. Our purpose is to help you learn about the r

CSAPP缓冲区溢出攻击实验(上)

CSAPP缓冲区溢出攻击实验(上) 下载实验工具.最新的讲义在这. 网上能找到的实验材料有些旧了,有的地方跟最新的handout对不上.只是没有关系,大体上仅仅是程序名(sendstring)或者參数名(bufbomb -t)的差异,不影响我们的实验. 1.实验工具 1.1 makecookie 后面实验中,五次"攻击"中有四次都是使你的cookie出如今它原本不存在的位置,所以我们首先要为自己产生一个cookie. 实验工具中的makecookie就是生成cookie用的.參数是你的

CSAPP缓冲区溢出攻击实验(下)

CSAPP缓冲区溢出攻击实验(下) 3.3 Level 2: 爆竹 实验要求 这一个Level的难度陡然提升,我们要让getbuf()返回到bang()而非test(),并且在执行bang()之前将global_value的值修改为cookie.因为全局变量与代码不在一个段中,所以我们不能让缓冲区一直溢出到.bss段(因为global_value初始化为0,所以它会被放在.bss而非.data段以节省空间)覆盖global_value的值.若修改了.bss和.text之间某些只读的段会引起操作系

CSAPP 六个重要的实验 lab5

CSAPP  && lab5 实验指导书: http://download.csdn.net/detail/u011368821/7951657 实验材料: http://download.csdn.net/detail/u011368821/8019293 搞定这个实验还是要看一下曾经的笔记,再复习一下block的组织方式.仅仅看link里面第11节,动态内存分配的部分就能够了 http://blog.csdn.net/cinmyheart/article/details/3813637

第六周总结 &amp; 实验报告(四)

第六周小结 一.instanceof关键字         在Java中使用instanceof关键字判断一个对象到底是哪个类的实例,返回boolean类型 1.instanceof关键字的作用 例class A{ public void fun1(){ System.out.println("A-->public void fun1(){}"); } public void fun2(){ this.fun1(); } } classB extends A{ public vo