深入理解程序设计linux汇编语言书中源码

1.1节

  1. 代码

     .section .data
     .section .text
     .globl _start
     _start:
      movl $1, %eax # 这事用于退出程序的linux内核命令号
      movl $0, %ebx # 这事我们将返回给操作系统的状态码
     			   # 改变这个数字,则返回到echo的值回不同
      int $0x80     # 这将唤醒内核,以运行退出命令
    
  2. 编译

     as exit.s -o exit.o
    
  3. 链接文件

     ld exit.o -o exit
    
  4. 执行

     ./exit
     echo $?
    

1.2 节

  1. maximum.s

     # 目的:本程序寻找一个组数据项中的最大值
     .section .data
     data_items: # 这些事数据项
     .long 3,67,34,222,45,75,54,34,44,33,22,11,66,0
     
     .section .text
     
     .globl _start
     _start:
      movl $0, %edi # 将0移入索引寄存器
      movl data_items(,%edi,4), %eax # 加载数据的第一个字节
      movl %eax, %ebx # 有余这事第一项,%eax就是最大值
     
     start_loop: # 开始循环
      cmpl $0, %eax # 检测是否到达数据末尾
      je loop_exit
      incl %edi # 加载下一个值
      movl data_items(,%edi,4), %eax
      cmpl %ebx, %eax # 比较值
      jle start_loop # 若数据项不大于原始值,则调到循环起始处
      movl %eax, %ebx # 将心智移入最大值寄存器
      jmp start_loop # 调到循环起始处
     
     loop_exit:
      # %ebx 是系统调用exit的状态吗
      # 已经存放了最大值
      movl $1, %eax # 1是exit()系统调用
      int $0x80
    

1.3

  1. power.s

     # 目的:展示函数如何工作的程序
     # 本程序计算2^3+5^2
     # 主程序中的所有内容都存储在寄存器中
     # 因此数据段不包含任何内容
     .section .data
     
     .section .text
     
     .globl _start
     _start:
      pushl $3 # 压入第二个参数
      pushl $2 # 压入第一个参数
      call power # 调用函数
      addl $8, %esp # 将栈指针向后移动
      pushl %eax # 在调用下一个函数之前,保存第一个答案
      pushl $2 # 压入第二个参数
      pushl $5 # 压入第一个参数
      call power #调用函数
      addl $8, %ebx # 将指针向后移动
      popl %ebx # 第二个答案已经在 %eax中,我们之前已经将第一个答案存储到占中,所以可以将其弹出到%ebx
      addl %eax, %ebx # 将两者相加,结果在%ebx中
     
      movl $1, %eax # 退出
      int $0x80
     
     # 目的:本函数用于计算一个数的幂
     
     .type power, @function
     power:
      pushl %ebx # 保留旧基址指针
      movl %esp, %ebp # 将基址指针设为栈指针
      subl $4, %esp # 为本地存储保留空间
      movl 8(%ebp),%ebx # 将第一个参数放入%eax
      movl 12(%ebp),%ecx # 将第二个参数放入%ecx
      movl %ebx,-4(%ebp) # 存储当前结果
     
     power_loop_start:
      cmpl $1,%ecx # 如果是1次方,那么我们已经获得结果
      je end_power
      movl -4(%ebp), %eax # 将结果移入%eax
      imull %ebx,%eax # 将当前结果与底数相乘
      movl %eax, -4(%ebp) # 保存当前结果
      decl %ecx # 指数递减
      jmp power_loop_start # 为递减后的指数激进型幂计算
     end_power:
      movl -4(%ebp),%eax # 返回值移入%eax
      movl %ebp,%esp # 恢复栈指针
      popl %ebp # 恢复基址指针
      ret
    
  2. 编译链接

     # -g 增加调试信息用于gdb
     # --32 按照32位编译,不加参数报错Segmentation fault
     as -g --32 -o power.o power.s
     ld -m elf_i386 -o power power.o
    
  3. 打印结果

     echo $?
    
  4. 调试信息

     # gdb的用法主要有几个:
     # list显示代码
     # break设置段点
     # info register显示所有寄存器的值
     # print打印特定变量的值
     # x显示特定内存位置的值
     # step下一指令
     # run运行代码
     
     gdb power
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值