showmemory.c 和 hello.s 源码
showmemory.c 和 hello.s 源码
1 /** 2 * showmemory.c -- print the position of different types of data in a program in the memory 3 */ 4 5 #include <sys/types.h> 6 #include <sys/ipc.h> 7 #include <sys/shm.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 #define ARRAY_SIZE 4000 12 #define MALLOC_SIZE 100000 13 #define SHM_SIZE 100000 14 #define SHM_MODE (SHM_R | SHM_W) /* user read/write */ 15 16 /* declare the address relative variables */ 17 extern char _start, __data_start, __bss_start, etext, edata, end; 18 extern char **environ; 19 20 char array[ARRAY_SIZE]; /* uninitialized data = bss */ 21 22 int main(int argc, char *argv[]) 23 { 24 int shmid; 25 char *ptr, *shmptr; 26 27 printf("===== memory map =====\n"); 28 printf(".text:\t0x%x->0x%x (_start, code text)\n", &_start, &etext); 29 printf(".data:\t0x%x->0x%x (__data_start, initilized data)\n", &__data_start, &edata); 30 printf(".bss: \t0x%x->0x%x (__bss_start, uninitilized data)\n", &__bss_start, &end); 31 32 /* shmid is a local variable, which is stored in the stack, hence, you 33 * can get the address of the stack via it*/ 34 35 if ( (ptr = malloc(MALLOC_SIZE)) == NULL) { 36 printf("malloc error!\n"); 37 exit(-1); 38 } 39 40 printf("heap: \t0x%x->0x%x (address of the malloc space)\n", ptr, ptr+MALLOC_SIZE); 41 42 if ( (shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0) { 43 printf("shmget error!\n"); 44 exit(-1); 45 } 46 47 if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1) { 48 printf("shmat error!\n"); 49 exit(-1); 50 } 51 printf("shm :\t0x%x->0x%x (address of shared memory)\n", shmptr, shmptr+SHM_SIZE); 52 53 if (shmctl(shmid, IPC_RMID, 0) < 0) { 54 printf("shmctl error!\n"); 55 exit(-1); 56 } 57 58 printf("stack:\t <--0x%x--> (address of local variables)\n", &shmid); 59 printf("arg: \t0x%x (address of arguments)\n", argv); 60 printf("env: \t0x%x (address of environment variables)\n", environ); 61 62 exit(0); 63 }
1 # hello.s 2 # 3 # $ as --32 -o hello.o hello.s 4 # $ ld -melf_i386 --oformat=binary -o hello hello.o 5 # $ export PATH=./:$PATH 6 # $ hello 0 0 0 7 # hello 8 # 9 10 .file "hello.s" 11 .global _start, _load 12 .equ LOAD_ADDR, 0x00010000 # Page aligned load addr, here 64k 13 .equ E_ENTRY, LOAD_ADDR + (_start - _load) 14 .equ P_MEM_SZ, E_ENTRY 15 .equ P_FILE_SZ, P_MEM_SZ 16 17 _load: 18 .byte 0x7F 19 .ascii "ELF" # e_ident, Magic Number 20 .long 1 # p_type, loadable seg 21 .long 0 # p_offset 22 .long LOAD_ADDR # p_vaddr 23 .word 2 # e_type, exec # p_paddr 24 .word 3 # e_machine, Intel 386 target 25 .long P_FILE_SZ # e_version # p_filesz 26 .long E_ENTRY # e_entry # p_memsz 27 .long 4 # e_phoff # p_flags, read(exec) 28 .text 29 _start: 30 popl %eax # argc # e_shoff # p_align 31 # 4 args, eax = 4, sys_write(fd, addr, len) : ebx, ecx, edx 32 # set 2nd eax = random addr to trigger bad syscall for exit 33 popl %ecx # argv[0] 34 mov $5, %dl # str len # e_flags 35 int $0x80 36 loop _start # loop to popup a random addr as a bad syscall number 37 .word 0x34 # e_ehsize = 52 38 .word 0x20 # e_phentsize = 32 39 .byte 1 # e_phnum = 1, remove trailing 7 bytes with 0 value 40 # e_shentsize 41 # e_shnum 42 # e_shstrndx
我第一次写makefile时就出错了。
问题是:Makefile:3: *** 遗漏分隔符 。 停止。
寻找了百度,也有好多解决办法,但是大部分是差不多的解答,感觉就是单纯的复制粘贴一样,也不够完整。我经过反复琢磨终于解决并弄懂其中之奥妙!什么奥妙呢?那就是抓住本质!如何抓?我们的先了解一定的概念,正确的对概念的认知和把握更有助于我们探知事物之奥秘。
1 shiftwidth
这个是用于程序中自动缩进所使用的空白长度指示的。一般来说为了保持程序的美观,和下面的参数最好一致。同时它也是符号移位长度的制定者。
2 tabstop
定义tab所等同的空格长度,一般来说最好设置成8,因为如果是其它值的话,可能引起文件在打印之类的场合中看起来很别扭。除非你设置了 expandtab
模式,也就是把tab转换成空格,这样的话就不会一起混淆,不过毕竟制表符为8是最常用最普遍的设置,所以一般还是不要改。
3 softtabstop
如果我们希望改变程序中的缩进怎么办?shiftwidth
和tabstop
不一样的话,你会发现程序比较难看的。这时候,softtabstop
就起作用了。可以从vim的说明中看到,一旦设置了softtabstop
的值时,你按下tab键,插入的是空格和tab制表符的混合,具体如何混合取决于你设定的softtabstop
,举个例子,如果设定softtabstop=8, 那么按下tab键,插入的就是正常的一个制表符;如果设定 softtabstop=16,那么插入的就是两个制表符;如果softtabstop=12,那么插入的就是一个制表符加上4个空格;如果 softtabstop
=4呢?那么一开始,插入的就是4个空格,此时一旦你再按下一次tab,这次的四个空格就会和上次的四个空格组合起来变成一个制表符。换句话说,softtabstop
是“逢8空格进1制表符”,前提是你tabstop=8
。
4 关于expandtab
举个例子,在多人一起开发项目时,为了使代码风格尽量保持一致,一般不允许在代码使用TAB符,而以4个空格代之。我们可以编辑一个文件,包含下面的内容:
set shiftwidth=4
set expandtab
然后把下面的命令加入到.vimrc中:autocmd FileType c,cpp set shiftwidth=4 | set expandtab
就可以只在编辑c和cpp文件时实行这种设置了
===============================================================================================================================
好了,注明一下,以上是我复制过来的,概念嘛,只要是正确的,怎么表达都一样,便于我们理解就行。
嘿嘿,现在进入解决make出现遗漏分隔符(linux)这个问题!
一,用vim编译器写makefile文件时出错,如果你的.vimrc配置没有问题的话,默认情况下是不会出错的,或者“正确的配置”情况下
如果你的.vimrc中有包含以下的信息(那就注意了):
---------------------------------
set softtabstop=4
set expandtab=4
或者写了
set softtabstop=4
---------------------------------
如果你们明白上面的概念,你就应该知道你错在哪里了,因为我们写makefile的时候不能用空格代替TAB!
--------------------------------------正确配置(相对而言的)---------------
set tabstop=4
set softtabstop=4
----------------------------------------------------------------
问题解决!
二,用gedit编译器编写makefile,您只要注意如下:
编译->首选项:"编辑器"选项页下,有一个"制位表",有一个复选框:插入空格代替制表符(s),把它勾掉就行就相当于您在vimrc中配置了expandtab一样的功能!
==============================================
下面我用图片展示一下我的错误。
这是我写的源程序文件,问题出现了,make时出现了遗漏。。。。
这是我们如果出现空格的话的表象,记住这个样子,您会发现真相原来就在这里!
(注意我的图片中写错了一个单词和换行符,后面有改正!)
这是问题之根因!
改正之后的
我测试过了!此时您加了tabstop之后,没有删除softtabstop也可行,而且比没有要好玩的多(个人觉得),不信您自己去尝试下,实践才好玩嘛!
注意, 此makefile中我写错了一个地方,您找到了吗?不过,我们的根本问题已经解决!
下面是正确的示范: