Chinaunix首页 | 论坛 | 博客
  • 博客访问: 117136
  • 博文数量: 24
  • 博客积分: 1411
  • 博客等级: 上尉
  • 技术积分: 261
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-07 17:49
文章分类

全部博文(24)

文章存档

2009年(24)

我的朋友

分类:

2009-08-09 21:21:29

摘自csapp 3.15.1。

这两个程序的目的判断32位乘法是否溢出,因为imull和mull在溢出时都会将CF标志设为1,setae命令设置al为~CF,最后返回eax判断是否溢出。

但是,这两个程序在 gcc4.4 下都不能按csapp原意编译(作者也说正确编译靠编译器的理解)

第一个程序,编译器认准了result = 0,无论加不加 -O -O2命令,最后都会把eax设为0

int ok_smull(int x, int y, int *dest)
{
  int result = 0;

  *dest = x*y;
  asm("setae %al");
  return result;
}



下面这个改进版,算计编译器会因为看见全局变量,不会对程序结构做什么大改动,但也错了

static int dummy = 0;

int ok_smull(int x, int y, int *dest)
{
  int result;

  *dest = x*y;
  result = dummy;
  asm("setae %al");
  return result;
}



看看下面的汇编代码,先把eax存起来,setae之后,再把eax取回来,所以setae一点用都没有了

__Z8ok_smulliiPi:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    8(%ebp), %eax
    movl    %eax, %edx
    imull    12(%ebp), %edx
    movl    16(%ebp), %eax
    movl    %edx, (%eax)
    movl    __ZL5dummy, %eax
    movl    %eax, -4(%ebp)
/APP
 # 9 "ok_smul.cpp" 1
    setae %al
 # 0 "" 2
/NO_APP
    movl    -4(%ebp), %eax
    leave
    ret


.......................................................
记录下每一小步,以防忘掉吧

阅读(1086) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~