美文网首页
K&G C语言 习题1.8

K&G C语言 习题1.8

作者: 半步江南 | 来源:发表于2018-12-03 20:36 被阅读8次

    1.8 编写一个统计空格、制表符、换行符的程序

    统计这些符号至少需要一个文件
    所以:需要先打开一个文件(传入-- 打开 读取 文件位置 权限等参数)

    open_fd_in:
    
            movl $5,%eax
            movl 8(%ebp),%ebx
            movl $0,%ecx
            movl $0666,%edx
            int $0x80
    

    然后:得到这个文件的标识符

    movl %eax,-4(%ebp)
    

    然后:读取这个文件(传入-- 读取 文件标识符 缓冲区 缓冲区空间 等参数)

            movl $3,%eax
            movl -4(%ebp),%ebx
            movl $BUFFER_DATA,%ecx
            movl $500,%edx
            int $0x80
            cmpl $0 , %eax
    

    然后:从缓冲区将信息写入另一文件。

            movl %eax,%edx
            movl $4,%eax
            movl -8(%ebp),%ebx
            movl $BUFFER_DATA,%ecx
            int $0x80
    
    

    以下程序陷入死循环,不知道问题,用GDB检查

    int main(int argc,char *argv[]){
      int fd_in,fd_out;
      int readnum,writenum;
      int flag=0;
      fd_in=open(argv[1] , O_RDONLY,0);//fd_in中接受到文件的标识号,在32位系统上,他是一个4字节的int值;
      fd_out=open(argv[2],O_WRONLY,0);//同上,只不过这次打开的是将要写入的文件。
      char buf[BUFSIZ];
      while (flag!=1){
      readnum=read(fd_in,buf,BUFSIZ);
      if (readnum=0)
        {flag=1;}
      else if(readnum=-1)
        {}
      else if(readnum<-1)
        {}
      else {
        write(fd_out,buf,readnum);
      }
      }
      return 0;
    }
    
    
    (gdb) display 
    (gdb) s
    open () at ../sysdeps/unix/syscall-template.S:81
    81  ../sysdeps/unix/syscall-template.S: No such file or directory.
    

    找到了问题,原因是找不到open(),这个函数需要include <fcntl.h>,加上再试:
    依然是:

    (gdb) s
    open () at ../sysdeps/unix/syscall-template.S:81
    81  ../sysdeps/unix/syscall-template.S: No such file or directory.
    

    去掉 include <stdio.h>再试发现有一个syscalls.h的头文件我没有包含,但是我的确没有这个头文件。
    算了,我自己写一个open函数好了。

    //open.c
    #include <stdio.h>
    int main(int argc,char *argv[]){
      int fd_in;
      fd_in=open(argv[1] ,0,0);//fd_in中接受到文件的标识号,在32位系统上,他是一个4字节的int值;
      printf("Hello,world! %d",fd_in);
      return fd_in;
    }
    
    ~                                                                                                      
    ~                                                                                                      
    ~  
    

    将.c文件编译成汇编文件
    gcc -S open.c -o open1.s

        .file   "open.c"
        .text
        .globl  _start
        .type   _start, @function
    _start:
    .LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        andl    $-16, %esp
        subl    $32, %esp
        movl    12(%ebp), %eax
        addl    $4, %eax
        movl    (%eax), %eax
        movl    $0, 8(%esp)
        movl    $0, 4(%esp)
        movl    %eax, (%esp)
        call    open
        movl    %eax, 28(%esp)
        movl    28(%esp), %eax
        leave
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
    .LFE0:
        .size   _start, .-_start
        .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4"
        .section    .note.GNU-stack,"",@progbits
    

    修改main为_start,(后注:这个方式会出现段错误,运行到_start时便会出错,感觉是因为main是函数,而_start替代main时也成为了函数)
    as open1.s -o open1.o
    然后编写open汇编函数

    .globl open
    .type open,@function
    open:
            pushl %ebp
            movl %esp,%ebp
            movl $5,%eax
            movl 8(%ebp),%ebx
            movl 12(%ebp),%ecx
            movl $0666,%edx
            int $0x80
    
    store_fd_in:
            movl %eax,-4(%ebp)
            movl %ebp,%esp
            pop %ebp
            ret
    
    

    as asmopen.s -o asmopen.o

    链接:
    root@192:~/workdir/KandG/1# ld open1.o asmopen.o -o target
    root@192:~/workdir/KandG/1# ./target in.txt
    Segmentation fault (core dumped)

    以下方法解决,open函数使用成功

    root@192:~/workdir/KandG/1# gcc -c open.c -o open2.o
    root@192:~/workdir/KandG/1# as asmopen.s -o asmopen.o
    root@192:~/workdir/KandG/1# gcc open2.o asmopen.o -o target1
    root@192:~/workdir/KandG/1# ./target1 ./in.txt
    Hello,world! 3root@192:~/workdir/KandG/1#

    nnYJ

    相关文章

      网友评论

          本文标题:K&G C语言 习题1.8

          本文链接:https://www.haomeiwen.com/subject/ewrycqtx.html