意外覆盖通用寄存器

Posted

技术标签:

【中文标题】意外覆盖通用寄存器【英文标题】:Accidental overwrite of general register 【发布时间】:2019-10-15 23:21:03 【问题描述】:

我正在做一个家庭作业,我们必须编写 cmets 来描述一些汇编代码在做什么。我是汇编新手,所以我无法确定以下代码是否有错误。

我使用的是 i686 架构(不完全确定这意味着 TBH)

这个程序determineGrade.s正被另一个程序cs3843p3Driver.o调用

############################## determineGrade #####################
# Purpose:
#   determineGrade determines the grade of a student based on a
#   1000 pt scale.
# Parameters:
#   i 8(%ebp)  int iG1       Grade 1
#   i 12(%ebp) int iG2       Grade 2
#   i 16(%ebp) int iG3       Grade 3
#   i 20(%ebp) int iG4       Grade 4
#   i 24(%ebp) int iG5       Grade 5
#   i 28(%ebp) int iG6       Grade 6
#   i 32(%ebp) int iG7       Grade 7
#   i 36(%ebp) int iG8       Grade 8
#   i 40(%ebp) int iG9       Grade 9
#   i 44(%ebp) int iG10      Grade 10
# Locals:
#   -4(%ebp)  int iqTot
#   -8(%ebp)  int iTot
# Notes:
#   Grade is determined by
#       ??
# Return Value:
#   total grade on a 1000 pt scale
# Register Usage
#   %eax - mostly working register until after .L7 then ??
  .file "determineGrade.s"
  .text
.globl determineGrade
  .type determineGrade, @function
determineGrade:
  pushl %ebp
  movl  %esp, %ebp
    pushl %ebx                # Save the caller's %ebx since we are using %ebx
  subl  $20, %esp
  movl  $0, -4(%ebp)          # Overrides the caller's %ebx?

看起来调用者的%ebx 值与iqTot 存储在同一位置,iqTot 定义为-4(%ebp)。调用者的%ebx 值是否被意外覆盖?

【问题讨论】:

是的,看起来有问题。 i686 表示 386(32 位代码),ISA 扩展至并包括 Pentium Pro:例如cmovfcomi 可能他们想在潜艇之后进行推送以保留当地人。 【参考方案1】:

我与教授再次核对,是的,%ebx 的存储值被iqTot 覆盖。调用determineGrade 的函数并不依赖%ebx 才能正常工作,所以教授决定留下错误,看看我们是否会注意到。显然我是唯一一个说出来的学生,所以他给了我额外的荣誉。

应该是:

iqTot 存储在 -8(%ebp) iTot 存储在 -12(%ebp)

【讨论】:

哈哈,我喜欢这是故意的。是的,调用者实际上并不依赖于保留寄存器是相当普遍的。它可以去任何一种方式。通常main 的调用者是宽容的,因为它没有太多状态,而main 本身依赖于编译器优化。 32 位 PIC 代码在历史上总是使用 EBX 作为 GOT 的指针,因此踩到它几乎总是会使调用者在 PIE 可执行文件中崩溃。但是现在 GCC 可以将 EIP 插入任何寄存器,并且可能不会选择 EBX。 (不过,由于没有 RIP 相对寻址,32 位 -fPIE / -fPIC 效率非常低。)

以上是关于意外覆盖通用寄存器的主要内容,如果未能解决你的问题,请参考以下文章

通用寄存器都有哪些?

通用寄存器和专用寄存器有啥区别和联系?

关于 GNU ARM 汇编程序的意外警告

8080_32位汇编-通用寄存器

汇编笔记二32位通用寄存器 以及 常用汇编指令

通用寄存器是