Fork me on Github Fork me on Gitee

C温故补缺(一):数据类型和基本类型占位

数据类型

基本类型:就是算术类型,包括整型实型

枚举类型:一组离散的整数

void类型:无可用值类型

派生类型:指针(*),数组([]),结构体(struct),共用体(union),函数(fun())

基本类型占位

32位平台:

整型 实型
short:2 float:4
int:4 double:8
long:4

16位平台:

整型 实型
int:2 float:4
short int/short:2 double:8
long int/long:2 long double:16

所有的整形加上unsigned就是无符号数,范围加倍,占位不变

char占一个字节

数据类型的本质

数据的类型只是一个标签,人为规定他们存什么样的数据,但实际int long是一样的内存空间:都是4个字节,32位.char则是1个字节,8位,这8位可以存8个二进制位,至于它是什么值,是由编译器处理的.对于cpu来说,都是相同的二进制位.

在gcc编译器中,char,int,unsigned/signed,short,long等整型是直接存储其二进制位的,他们在表示数时只是长度和范围不同,还有以及规定的输出格式不同(%c和%d)

而float和double两个浮点型是用专门的标志标记其类型的

如:

int main(){
    char c='a';
    int a=1;
    int a1=2;
    int a2=3;
    float b1=4;
    float b2=5.5f;
    double b5=6;
    double b6=7.7f;
    return 0;
}

定义了char,int,float和double型的变量并赋值,看其汇编后的结果

    call    __main
    movb    $97, -1(%rbp)
    movl    $1, -8(%rbp)
    movl    $2, -12(%rbp)
    movl    $3, -16(%rbp)
    movss    .LC0(%rip), %xmm0
    movss    %xmm0, -20(%rbp)
    movss    .LC1(%rip), %xmm0
    movss    %xmm0, -24(%rbp)
    movsd    .LC2(%rip), %xmm0
    movsd    %xmm0, -32(%rbp)
    movsd    .LC3(%rip), %xmm0
    movsd    %xmm0, -40(%rbp)
    movl    $0, %eax
    addq    $80, %rsp
    popq    %rbp
    ret
    .seh_endproc
    .section .rdata,"dr"
    .align 4
.LC0:
    .long    1082130432
    .align 4
.LC1:
    .long    1085276160
    .align 8
.LC2:
    .long    0
    .long    1075314688
    .align 8
.LC3:
    .long    -1073741824
    .long    1075760332
    .ident    "GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"

可以看到,char和int型在汇编时都是直接把操作数mov到bp寄存器的,也就是cpu可以直接操作其运算

而float和double则存在IP指令指针寄存器,并用LC标志其类型和内存对齐系数,也就是说,浮点数需要额外的指令来操作,并最终在Xmm寄存器运算

Xmm寄存器

XMM寄存器是一个完全独立的寄存器集,随SSE(浮点数指令集)一起引入,至今仍广泛使用。它们的宽度为128位,其指令可以将它们视为64、32(整数和浮点),16或8位(仅整数)值的数组。在32位模式下有8个,在64位模式下有16个。几乎所有浮点数学运算都是在64位模式下在SSE(以及XMM寄存器)中完成的

posted @ 2022-11-10 16:17  Tenerome  阅读(55)  评论(0编辑  收藏  举报