oggplay 发表于 2014-5-12 22:48:01

=============整数看完,接着浮点数了==============



例题:将1234510转换为二进制浮点12345.0 IEEE表示,并利用show_float()函数验证是否正确。

1234510=],将二进制小数点左移13位,于是我们得到规约化表示1.10000001110012×2^13。根据IEEE表示,去掉小数点前面的1,并在末尾添加10个0,来构造小数位,得到二进制。13加32位浮点偏置量127=140,140二进制表示。加上符号位0,我们就得到二进制的浮点表示。那么单精度浮点值12345.0十六进制就是0x4640E400。

oggplay 发表于 2014-5-14 22:19:27

本帖最后由 oggplay 于 2014-5-14 22:59 编辑

***IEEE浮点运算(包括其中阿贝尔群)先忽略不看。:dizzy:
======================================
所有C语言版本提供两种不同的浮点数据类型:float和double。C语言标准不要求机器使用IEEE浮点,所以没有标准的方式或者得到诸如-0、正无穷,负无穷、NaN之类的特殊值。大多数系统提供了include文件和读取这些特征的过程库,但是细节各不相同。例如GCC会定义常数INFINITY和NAN。

#define _GNU_source 1
#include <math.h>

较新版本包括C99,包含long double数据类型。大多数编译器认为等价于double。不过对于intel兼容机,GCC用80位格式来实现这种数据类型,提供了比64位格式大的多的取值精度(学过80386汇编的应该清楚,IA32系列如intel、amd,浮点寄存器 st0,st1....st7)。
=======================================
以下int为32位:
*从int转换成float,数字不会溢出,但是可能被舍入
*从int或float转换成double,不受影响
*从double转换成float,可能溢出成正无穷或负无穷或舍入。
*从float或者double转换成int,值会向零舍入或溢出。例如1.999被转换成1,而-1.999将被转换成-1。从浮点数到整数的转换,如果不能为浮点数找到一个合理的整数近似值,就会产生一个不确定值(intel兼容处理器指定位模式2)。因此(int)+1e10会得到-21483648,即从一个正值变成了一个负值。C标准并没有指定溢出结果。

微笑的好吧 发表于 2014-5-15 14:30:00

加油{:1_1:}{:1_1:} 支持一下

oggplay 发表于 2014-5-28 17:00:10

本帖最后由 oggplay 于 2014-5-28 17:20 编辑

第一部分第二章结束,课后练习继续中,下面开始第三章
===========================================
AT&T汇编终于派上用场。


char-->int                         movsbl   %al,(%edx)
char-->unsigned                movsbl   %al,(%edx)
unsigned char-->int         movzbl   %al,(%edx)
int-->char                         movb   %al,(%edx)
unsigned-->unsigned charmovb   %al,(%edx)
unsigned-->int                  movl   %eax,(%edx)

oggplay 发表于 2014-5-31 10:25:51

本帖最后由 oggplay 于 2014-5-31 10:27 编辑

考虑下面的C函数原型,其中num_t是typedef声明的数据类型。
void store_prod(num_t *dest, unsigned x, num_t y) {
   *dest=x*y;
}
gcc 产生以下汇编代码来实现计算主体:
movl 12(%ebp), %eax
movl 20(%ebp), %ecx
imull %eax, %ecx
mull 16(%ebp)
leal(%ecx,%edx), %edx
movl 8(%ebp), %ecx
movl %eax, (%ecx)
movl %edx, 4(%ecx)
可以看到,这段代码需要读两次内存来取参数(第2行,第4行),两次乘法(第3、第4),以及两次内存写来存储结果(第7、第8)
A.num_t是什么数据类型?
B.描述计算乘积的算法,验证其正确性。

feiyingbuke 发表于 2014-5-31 15:31:58

有什么用?

oggplay 发表于 2014-6-6 11:16:03

本帖最后由 oggplay 于 2014-6-6 21:44 编辑

控制,条件传送部分
根据汇编代码补充C代码:
int test (int x, int y) {
          int val = ________;
          if (_____) {
               if (_______)
                  val = _______;
               else
                  val = _______;
                   }
          else if (______)
                  val = ________;
      return val;
}



GCC产生如下的汇编代码:
x at %ebp+8 , y at %ebp+12   movl    8(%ebp), %ebx
   movl    12(%ebp),%ecx
   testl   %ecx, %ecx
   jle   .L2
   movl    %ebx, %edx
   subl    %ecx, %edx
   movl    %ecx, %eax
   xorl    %ebx, %eax
   cmpl    %ecx, %ebx
   cmovl   %edx, %eax   
   jmp   .L4
.L2:
   leal    0(,%ebx,4), %edx
   leal    (%ecx, %ebx), %eax
   cmpl    $-2, %ecx
   cmovage%edx, %eax
.L4:=============================================
以上是书本32位GCC逻辑,与本人64位clang逻辑已有很大不同
         movl      %edi, -4(%rbp)
         movl      %esi, -8(%rbp)
         movl      -4(%rbp), %esi
         shll      $2, %esi
         movl      %esi, -12(%rbp)
         cmpl      $0, -8(%rbp)
         jle      .LBB0_5

         movl      -4(%rbp), %eax
         cmpl      -8(%rbp), %eax
         jge      .LBB0_3

         movl      -4(%rbp), %eax
         subl      -8(%rbp), %eax
         movl      %eax, -12(%rbp)
         jmp      .LBB0_4
.LBB0_3:
          movl      -4(%rbp), %eax
          xorl      -8(%rbp), %eax
          movl      %eax, -12(%rbp)
.LBB0_4:
         jmp      .LBB0_8
.LBB0_5:
         cmpl      $-2, -8(%rbp)
         jge      .LBB0_7

         movl      -4(%rbp), %eax
         addl      -8(%rbp), %eax
         movl      %eax, -12(%rbp)
.LBB0_7:
         jmp      .LBB0_8
.LBB0_8:
         movl      -12(%rbp), %eax


lf19891031 发表于 2014-6-6 17:04:09

看不懂啊郁闷呢

qq893161525 发表于 2014-6-7 16:55:27

能坚持????

ahnupeng 发表于 2014-6-7 22:57:56

每日一练,一练一日。

oggplay 发表于 2014-6-8 22:07:53

本帖最后由 oggplay 于 2014-6-8 22:13 编辑

do-while,while语句学完然后是swtich语句:
int switch_eg(int x , int n){
int result=x;

switch (n) {

case 100:
      result*=13;
      break;

case 102:
      result+=100;
      break;

case 103:
      result+=11;
      break;

case 104:
case 106:
       result*=result;
       break;      

default:
    result=0;
}
return result;
}


将自己64位编译器汇编代码取代书本32位,逻辑都是一样的:

      .file      "1.c"
      .text
      .globl      switch_eg
      .align      16, 0x90
      .type      switch_eg,@function
switch_eg:                              # @switch_eg
      .cfi_startproc
# BB#0:
      pushq      %rbp
.Ltmp2:
      .cfi_def_cfa_offset 16
.Ltmp3:
      .cfi_offset %rbp, -16
      movq      %rsp, %rbp
.Ltmp4:
      .cfi_def_cfa_register %rbp
      movl      %edi, -4(%rbp)
      movl      %esi, -8(%rbp)
      movl      -4(%rbp), %esi
      movl      %esi, -12(%rbp)
      movl      -8(%rbp), %esi
      addl      $-100, %esi
      movl      %esi, %eax
      subl      $6, %esi
      movq      %rax, -24(%rbp)         # 8-byte Spill
      movl      %esi, -28(%rbp)         # 4-byte Spill
      ja      .LBB0_5
# BB#7:
      movq      -24(%rbp), %rax         # 8-byte Reload
      movq      .LJTI0_0(,%rax,8), %rcx
      jmpq      *%rcx
.LBB0_1:
      imull      $13, -12(%rbp), %eax
      movl      %eax, -12(%rbp)
      jmp      .LBB0_6
.LBB0_2:
      movl      -12(%rbp), %eax
      addl      $100, %eax
      movl      %eax, -12(%rbp)
      jmp      .LBB0_6
.LBB0_3:
      movl      -12(%rbp), %eax
      addl      $11, %eax
      movl      %eax, -12(%rbp)
      jmp      .LBB0_6
.LBB0_4:
      movl      -12(%rbp), %eax
      movl      -12(%rbp), %ecx
      imull      %eax, %ecx
      movl      %ecx, -12(%rbp)
      jmp      .LBB0_6
.LBB0_5:
      movl      $0, -12(%rbp)
.LBB0_6:
      movl      -12(%rbp), %eax
      popq      %rbp
      ret
.Ltmp5:
      .size      switch_eg, .Ltmp5-switch_eg
      .cfi_endproc
      .section      .rodata,"a",@progbits
      .align      8
.LJTI0_0:
      .quad      .LBB0_1
      .quad      .LBB0_5
      .quad      .LBB0_2
      .quad      .LBB0_3
      .quad      .LBB0_4
      .quad      .LBB0_5
      .quad      .LBB0_4


      .section      ".note.GNU-stack","",@progbits

网络学习 发表于 2014-6-9 00:26:59

厚积薄发 穷且益坚

oggplay 发表于 2014-6-25 14:24:08

本帖最后由 oggplay 于 2014-6-25 14:29 编辑

给你个任务,检查一下C编译器为结构和联合的访问产生正确的代码,你写了下面的结构声明:typedef union {
    struct   {
      shortv;
      shortd;
      int      s;
} t1;
    struct {
         int a;
         char*p;
   } t2;
} u_type;   你写了一组具有下面这种形式的函数

void get (u_type *up, TYPE *dest) {
    *dest = EXPR;
}
这组函数有不一样的访问表达式EXPR,而且根据EXPR的类型来设置目的数据类型TYPE。然后再检查编译这些函数时产生的代码,看看它们是否与你期待的一样。
假设在这些函数中,up和dest分别被加载到寄存器%eax和%edx中。填写下表中的数据类型TYPE,并用1~3条指令来计算表达式,将结果存储在dest中。试着只使用%edx和%eax,不够时再使用%ecx。




oggplay 发表于 2014-6-25 15:19:38

这一小节比较生疏,但是又很重要,不得不分享一下。

数据对齐:







龙舞杀 发表于 2014-6-25 22:52:41

这是要探究一些底层的东西?还没仔细看。。。

oggplay 发表于 2014-6-27 15:00:44

本帖最后由 oggplay 于 2014-6-27 16:24 编辑

http://bbs.fishc.com/thread-48826-1-1.html 这是栈溢出的一个例子。以下是限制栈溢出的几种策略。

















破灬王 发表于 2014-6-27 15:49:26

楼主加油!!!

水鱼 发表于 2014-6-27 16:59:40

越来越搞不懂了

七月你好 发表于 2014-6-27 17:25:56


祝坚持!厚积薄发~

zfw4161 发表于 2014-6-27 22:26:01

      过来看看啊 好东西
页: 1 [2] 3
查看完整版本: 每日一练!从零开始学习。。。。。。