鱼C论坛

 找回密码
 立即注册
楼主: oggplay

[技术交流] 每日一练!从零开始学习。。。。。。

[复制链接]
 楼主| 发表于 2014-5-12 22:48:01 | 显示全部楼层
=============整数看完,接着浮点数了==============
2.png
3.png

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

1234510=[11000000111001],将二进制小数点左移13位,于是我们得到规约化表示
[/b]1.10000001110012×2^13。根据IEEE表示,去掉小数点前面的1,并在末尾添加10个0,来构造小数位,得到二进制[10000001110010000000000]。13加32位浮点偏置量127=140,140二进制表示[10001100]。加上符号位0,我们就得到二进制的浮点表示[01000110010000001110010000000000]。那么单精度浮点值12345.0十六进制就是0x4640E400。
4.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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兼容处理器指定位模式[100...00]2)。因此(int)+1e10会得到-21483648,即从一个正值变成了一个负值。C标准并没有指定溢出结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-15 14:30:00 | 显示全部楼层
加油{:1_1:}{:1_1:} 支持一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-5-28 17:00:10 | 显示全部楼层
本帖最后由 oggplay 于 2014-5-28 17:20 编辑

第一部分第二章结束,课后练习继续中,下面开始第三章
===========================================
AT&T汇编终于派上用场。
1.png
2.png
char-->int                         movsbl   %al,(%edx)
char-->unsigned                movsbl   %al,(%edx)
unsigned char-->int           movzbl   %al,(%edx)
int-->char                         movb     %al,(%edx)
unsigned-->unsigned char  movb     %al,(%edx)
unsigned-->int                  movl     %eax,(%edx)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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.描述计算乘积的算法,验证其正确性。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-5-31 15:31:58 | 显示全部楼层
有什么用?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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
  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-6 17:04:09 | 显示全部楼层
看不懂啊  郁闷呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-7 16:55:27 | 显示全部楼层
能坚持????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-7 22:57:56 | 显示全部楼层
每日一练,一练一日。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-9 00:26:59 | 显示全部楼层
厚积薄发 穷且益坚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-25 14:24:08 | 显示全部楼层
本帖最后由 oggplay 于 2014-6-25 14:29 编辑

给你个任务,检查一下C编译器为结构和联合的访问产生正确的代码,你写了下面的结构声明:
typedef union {
    struct   {
        short  v;
        short  d;
        int      s;
} t1;
    struct {
         int a[2];
         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。


11.png


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-25 15:19:38 | 显示全部楼层
这一小节比较生疏,但是又很重要,不得不分享一下。

数据对齐:
11.png
12.png
13.png
14.png



想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-25 22:52:41 | 显示全部楼层
这是要探究一些底层的东西?还没仔细看。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2014-6-27 15:00:44 | 显示全部楼层
本帖最后由 oggplay 于 2014-6-27 16:24 编辑

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



1.png
2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png
10.png




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-27 15:49:26 | 显示全部楼层
楼主加油!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-27 16:59:40 | 显示全部楼层
越来越搞不懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-27 17:25:56 | 显示全部楼层

祝坚持!厚积薄发~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-6-27 22:26:01 | 显示全部楼层
      过来看看啊 好东西
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-29 14:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表