精华内容
下载资源
问答
  • 有时我们需要编写DOS实模式下的CPU信息诊断程序,但是TurboC++等很多16位C++编译器不支持CPUID指令和32位汇编。于是本文介绍了一种办法,靠内嵌机器码实现了获取CPUID信息。 一、CPUID指令简介  CPUID指令是intel...

      有时我们需要编写DOS实模式下的CPU信息诊断程序,但是TurboC++等很多16位C++编译器不支持CPUID指令和32位汇编。于是本文介绍了一种办法,靠内嵌机器码实现了获取CPUID信息。

    一、CPUID指令简介

      CPUID指令是intel IA32架构下获得CPU信息的汇编指令,可以得到CPU类型,型号,厂商信息,商标信息,序列号,缓存等一系列CPU相关的东西。

      CPUID指令一般使用使用eax作为输入参数(某些时候会用到ecx),eax、ebx、ecx、edx作为输出参数。例如这样的汇编代码——

    mov    eax, 1
    cpuid
    ...

     

      以上代码以1为输入参数,执行cpuid后,eax、ebx、ecx、edx的值都被返回值填充。针对不同的输入参数eax的值,输出参数的意义都不相同。具体含义可参考Intel和AMD的手册——
    《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z》. May 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
    《Intel® Processor Identification and the CPUID Instruction》. April 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
    《AMD CPUID Specification》. September 2010. http://support.amd.com/us/Embedded_TechDocs/25481.pdf

    二、将CPUID封转为函数

      用汇编语言来做软件开发的成本很高,所以一般使用C++等高级语言来做软件开发,于是我们希望能将CPUID指令封装为函数。
      但现在遇到一个难题——虽然TurboC++等16位C++编译器支持asm语句来实现内嵌汇编,但它只支持16位汇编,不支持CPUID指令和32位汇编。该怎么办呢?

      幸好TurboC++支持在asm语句插入机器码。比如我们可以将CPUID指令的机器码插入到asm语句中——

        _asm{
            ...
            db 0x0f; db 0xa2;    // cpuid
            ...
        }

     

      “0f a2”是CPUID指令的机器码,在Intel手册上可以查到——

      现在我们又遇到一个难题——CPUID指令使用了eax、ebx、ecx、edx这几个32位寄存器,但TurboC++中的内嵌汇编只支持16位汇编,既只能访问ax、bc、cx、dx。
      这时,可以使用66h前缀来调整操作数的大小(66H prefix - Operand Size Override)。给一条16位指令加上66H前缀时,它的操作数——既寄存器宽度变为了32位。比如原16位指令用的是ax,加上66H前缀时变为eax。注意此时的内存寻址方式仍是16位的,仅是操作数变为32位,例如——

        _asm{
            db 0x66; mov ax, [di];    // mov eax, DWORD PTR [di]
        }

    注:在16位代码中要想使用32位寻址,得使用67H前缀来调整地址大小(67H prefix - Address Size Override)。本文没有用到,读者可自行学习。

      利用上述知识,我们可以构造CPUID函数了——

    // 获得CPU信息(加强版)
    //
    // pdwout4: 返回eax, ebx, ecx, edx这四个寄存器的值。
    // id: 功能ID。既CPUID指令的eax参数。
    // subid: 子功能ID。既CPUID指令的ecx参数。
    void getcpuidex(DWORD* pdwout4, DWORD id, DWORD subid)
    {
        if (NULL==pdwout4)    return;
        pdwout4[0] = id;    // eax
        pdwout4[2] = subid;    // ecx
        _asm{
            // load. 读取参数到寄存器
            mov di, pdwout4;    // 准备用di寻址pdwout4
            db 0x66; mov cx, [di+8];    // mov ecx, DWORD PTR [di+8]
            db 0x66; mov ax, [di];    // mov eax, DWORD PTR [di]
            db 0x66; xor dx, dx;    // xor edx, edx
            db 0x66; xor bx, bx;    // xor ebx, ebx
            // CPUID
            db 0x0f; db 0xa2;    // cpuid
            // save. 将寄存器保存到pdwout4
            db 0x66; mov [di], ax;    // mov DWORD PTR [di], eax
            db 0x66; mov [di+4], bx;    // mov DWORD PTR [di+4], ebx
            db 0x66; mov [di+8], cx;    // mov DWORD PTR [di+8], ecx
            db 0x66; mov [di+12], dx;    // mov DWORD PTR [di+12], edx
        }
    }

     

      注解——
    1. 因为CPUID的返回值会占满eax、ebx、ecx、edx这四个通用寄存器,所以利用di寄存器来寻址。
    2. 为了减少寄存器占用,将输入参数id、subid写入pdwout4,然后再在汇编代码中通过di寄存器寻址来加载参数。
    3. 虽然对于CPUID指令来说,不需要“xor edx, edx”等指令将edx、dbx清零。但考虑某些16位编译器对内嵌汇编的支持性不够好,手工写上dx、bx后能让编译器知道该内嵌汇编代码用到这2个寄存器,不会将这2个寄存器挪作他用。

      上面我们采用了内嵌机器码的形式实现了getcpuidex函数。但手工编写机器码是很容易出错的,怎样才能验证机器码是正确的呢?这时可以先将程序编译为exe,然后利用反汇编器来解析机器码。例如我用IDA Pro打开编译后的exe,因为现在程序很短小,能很快的找到调用cpuid指令的地方——

      反汇编的结果与我们预想的相同,验证通过。

    三、常用的CPUID功能

    3.1 取得CPU厂商(Vendor)

      把eax = 0作为输入参数,可以得到CPU的厂商信息。
      cpuid指令执行以后,会返回一个12字符的厂商信息,前四个字符的ASC码按低位到高位放在ebx,中间四个放在edx,最后四个字符放在ecx。比如说,对于intel的cpu,会返回一个“GenuineIntel”的字符串,返回值的存储格式为——  
            31      23      15      07      00
            EBX| u (75)| n (6E)| e (65)| G (47)
            EDX| I (49)| e (65)| n (6E)| i (69)
            ECX| l (6C)| e (65)| t (74)| n (6E)

      代码为——

    // 取得CPU厂商(Vendor)
    //
    // result: 成功时返回字符串的长度(一般为12)。失败时返回0。
    // pvendor: 接收厂商信息的字符串缓冲区。至少为13字节。
    int cpu_getvendor(char* pvendor)
    {
        DWORD dwBuf[4];
        if (NULL==pvendor)    return 0;
        // Function 0: Vendor-ID and Largest Standard Function
        getcpuid(dwBuf, 0);
        // save. 保存到pvendor
        *(DWORD*)&pvendor[0] = dwBuf[1];    // ebx: 前四个字符
        *(DWORD*)&pvendor[4] = dwBuf[3];    // edx: 中间四个字符
        *(DWORD*)&pvendor[8] = dwBuf[2];    // ecx: 最后四个字符
        pvendor[12] = '\0';
        return 12;
    }

     

    3.2 取得CPU商标(Brand)

      在我的电脑上点击右键,选择属性,可以在窗口的下面看到一条CPU的信息,这就是CPU的商标字符串。CPU的商标字符串也是通过cpuid得到的。由于商标的字符串很长(48个字符),所以不能在一次cpuid指令执行时全部得到,所以intel把它分成了3个操作,eax的输入参数分别是0x80000002,0x80000003,0x80000004,每次返回的16个字符,按照从低位到高位的顺序依次放在eax, ebx, ecx, edx。
      为了稳妥,最好事先调用0x80000000号功能检查一下扩展功能号的范围。

      代码为——

    // 取得CPU商标(Brand)
    //
    // result: 成功时返回字符串的长度(一般为48)。失败时返回0。
    // pbrand: 接收商标信息的字符串缓冲区。至少为49字节。
    int cpu_getbrand(char* pbrand)
    {
        DWORD dwBuf[4];
        if (NULL==pbrand)    return 0;
        // Function 0x80000000: Largest Extended Function Number
        getcpuid(dwBuf, 0x80000000UL);
        if (dwBuf[0] < 0x80000004UL)    return 0;
        // Function 80000002h,80000003h,80000004h: Processor Brand String
        getcpuid((DWORD*)&pbrand[0], 0x80000002UL);    // 前16个字符
        getcpuid((DWORD*)&pbrand[16], 0x80000003UL);    // 中间16个字符
        getcpuid((DWORD*)&pbrand[32], 0x80000004UL);    // 最后16个字符
        pbrand[48] = '\0';
        return 48;
    }

     

    四、全部代码

      全部代码——

    #include <stdio.h>
    
    typedef unsigned long DWORD;
    
    char szBuf[64];
    DWORD dwBuf[4];
    
    // 获得CPU信息(加强版)
    //
    // pdwout4: 返回eax, ebx, ecx, edx这四个寄存器的值。
    // id: 功能ID。既CPUID指令的eax参数。
    // subid: 子功能ID。既CPUID指令的ecx参数。
    void getcpuidex(DWORD* pdwout4, DWORD id, DWORD subid)
    {
        if (NULL==pdwout4)    return;
        pdwout4[0] = id;    // eax
        pdwout4[2] = subid;    // ecx
        _asm{
            // load. 读取参数到寄存器
            mov di, pdwout4;    // 准备用di寻址pdwout4
            db 0x66; mov cx, [di+8];    // mov ecx, DWORD PTR [di+8]
            db 0x66; mov ax, [di];    // mov eax, DWORD PTR [di]
            db 0x66; xor dx, dx;    // xor edx, edx
            db 0x66; xor bx, bx;    // xor ebx, ebx
            // CPUID
            db 0x0f; db 0xa2;    // cpuid
            // save. 将寄存器保存到pdwout4
            db 0x66; mov [di], ax;    // mov DWORD PTR [di], eax
            db 0x66; mov [di+4], bx;    // mov DWORD PTR [di+4], ebx
            db 0x66; mov [di+8], cx;    // mov DWORD PTR [di+8], ecx
            db 0x66; mov [di+12], dx;    // mov DWORD PTR [di+12], edx
        }
    }
    
    // 获得CPU信息
    void getcpuid(DWORD* pdwout4, DWORD id)
    {
        getcpuidex(pdwout4, id, 0);
    }
    
    // 取得CPU厂商(Vendor)
    //
    // result: 成功时返回字符串的长度(一般为12)。失败时返回0。
    // pvendor: 接收厂商信息的字符串缓冲区。至少为13字节。
    int cpu_getvendor(char* pvendor)
    {
        DWORD dwBuf[4];
        if (NULL==pvendor)    return 0;
        // Function 0: Vendor-ID and Largest Standard Function
        getcpuid(dwBuf, 0);
        // save. 保存到pvendor
        *(DWORD*)&pvendor[0] = dwBuf[1];    // ebx: 前四个字符
        *(DWORD*)&pvendor[4] = dwBuf[3];    // edx: 中间四个字符
        *(DWORD*)&pvendor[8] = dwBuf[2];    // ecx: 最后四个字符
        pvendor[12] = '\0';
        return 12;
    }
    
    // 取得CPU商标(Brand)
    //
    // result: 成功时返回字符串的长度(一般为48)。失败时返回0。
    // pbrand: 接收商标信息的字符串缓冲区。至少为49字节。
    int cpu_getbrand(char* pbrand)
    {
        DWORD dwBuf[4];
        if (NULL==pbrand)    return 0;
        // Function 0x80000000: Largest Extended Function Number
        getcpuid(dwBuf, 0x80000000UL);
        if (dwBuf[0] < 0x80000004UL)    return 0;
        // Function 80000002h,80000003h,80000004h: Processor Brand String
        getcpuid((DWORD*)&pbrand[0], 0x80000002UL);    // 前16个字符
        getcpuid((DWORD*)&pbrand[16], 0x80000003UL);    // 中间16个字符
        getcpuid((DWORD*)&pbrand[32], 0x80000004UL);    // 最后16个字符
        pbrand[48] = '\0';
        return 48;
    }
    
    int main(void)
    {
        //getcpuidex(dwBuf, 0,0);
        //printf("%.8lX\t%.8lX\t%.8lX\t%.8lX\n", dwBuf[0],dwBuf[1],dwBuf[2],dwBuf[3]);
    
        cpu_getvendor(szBuf);
        printf("CPU Vendor:\t%s\n", szBuf);
    
        cpu_getbrand(szBuf);
        printf("CPU Name:\t%s\n", szBuf);
    
        return 0;
    }

     

    五、编译和运行

      在Turbo C++ 3.0和Borland C++ 3.1中编译通过。将编译后的exe放在C盘根目录。然后重启电脑进入DOS实模式,运行成功——

      在Windows的命令提示符中也运行成功——

     

    参考文献——
    《Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z》. May 2012. http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.html
    《Intel® Processor Identification and the CPUID Instruction》. April 2012. http://developer.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
    《AMD CPUID Specification》. September 2010. http://support.amd.com/us/Embedded_TechDocs/25481.pdf
    《DOS下使用32位寄存器及CPUID》。senvei著。http://hi.baidu.com/senvei/blog/item/4820c11b4ad4e09b6438db64.html
    《x86/x64 指令编码内幕(适用于 AMD/Intel)》中的“2. 深入了解 prefix”。mik著。http://www.mouseos.com/x64/doc3.html
    《在C++中使用cpuid指令获得CPU信息》。闲人(freeman)著。http://freeman.cnblogs.com/archive/2005/08/30/226128.html
    http://en.wikipedia.org/wiki/CPUID
    http://baike.baidu.com/view/1829765.htm

     

    源码下载——
    http://files.cnblogs.com/zyl910/getcpuid.rar

    转载于:https://www.cnblogs.com/zyl910/archive/2012/05/14/dos16_getcpuid.html

    展开全文
  • ARM C/C++编译器可以被使用... 其中,armcc用于将遵循ANSI C标准C语言源程序编译成32位的ARM指令代码,它通过了Plum Hall C Validatin Suite测试。armcpp用于将遵循ANSI C++或者EC++标准C++语言源程序编译成
  • ARM C/C++编译器

    2021-01-19 22:56:59
    ARM C/C++编译器可以被使用... 其中,armcc用于将遵循ANSI C标准C语言源程序编译成32位的ARM指令代码,它通过了Plum Hall C Validatin Suite测试。armcpp用于将遵循ANSI C++或者EC++标准C++语言源程序编译成
  • TNT Realtime DOS-Extender 支持DOS下多线程序的运行时程序。 微软的 Foxpro 的32位版本程序,就是使用本产品开发。 FOXPROX.EXE 是 Foxpro 的32位版,一个文件即可完美运行所有的 Foxpro 功能。 TNT DOS-...
  • 安装:直接解包到c:\下,在DOS窗口中运行c:\turboc2下的tc.exe即可 /////////// devcpp-5.1.1.0_32bit_setup: WINDOWS下运行的C语言的集成开发环境,基于GCC编译器。 直接双击安装,而后开始菜单的程序组中点击运行...
  •  int型字长问题: ① C/C++规定int字长和机器字长相同; ② 操作系统字长和机器字长未必一致; ③ 编译器根据操作系统字长来定义int字长;... 由上面三点可知,在一些没有操作系统...比如你在64机器上运行DOS16
    

    int型字长问题:

    ① C/C++规定int字长和机器字长相同;

    ② 操作系统字长和机器字长未必一致;

    ③ 编译器根据操作系统字长来定义int字长;

      由上面三点可知,在一些没有操作系统的嵌入式计算机系统上,int的长度与处理器字长一致;有操作

    系统时,操作系统的字长与处理器的字长不一定一致,此时编译器根据操作系统的字长来定义int字长:"

    比如你在64位机器上运行DOS16系统,那么所有for dos16的C/C++编译器中int都是16位的;在64位机器上

    运行win32系统,那么所有for win32的C/C++编译器中int都是32位的"

    常见基本类型的字节大小

    32位操作系统

    char :1个字节(固定)

    *(即指针变量): 4个字节(32位机的寻址空间是4个字节。同理64位编译器)(变化*)

    short int : 2个字节(固定)

    int: 4个字节(固定)

    unsigned int : 4个字节(固定)

    float: 4个字节(固定)

    double: 8个字节(固定)

    long: 4个字节

    unsigned long: 4个字节(变化*,其实就是寻址控件的地址长度数值)

    long long: 8个字节(固定)


    64位操作系统

    char :1个字节(固定)

    *(即指针变量): 8个字节

    short int : 2个字节(固定)

    int: 4个字节(固定)

    unsigned int : 4个字节(固定)

    float: 4个字节(固定)

    double: 8个字节(固定)

    long: 8个字节

    unsigned long: 8个字节(变化*其实就是寻址控件的地址长度数值)

    long long: 8个字节(固定)
     

    除了*与long随操作系统子长变化而变化外,其他的都固定不变(32位和64相比)

    bool 1个字节  char 1个字节      int 4个字节   float 4个字节       doubl 8个字节   long long 8个字节

    展开全文
  • TNT Realtime DOS-Extender 支持DOS下多线程序的运行时程序。 微软的 Foxpro 的32位版本程序,就是使用本产品开发。 FOXPROX.EXE 是 Foxpro 的32位版,一个文件即可完美运行所有的 Foxpro 功能。 TNT DOS-...
  • TNT Realtime DOS-Extender 支持DOS下多线程序的运行时程序。 微软的 Foxpro 的32位版本程序,就是使用本产品开发。 FOXPROX.EXE 是 Foxpro 的32位版,一个文件即可完美运行所有的 Foxpro 功能。 TNT DOS-...
  • TNT Realtime DOS-Extender 支持DOS下多线程序的运行时程序。 微软的 Foxpro 的32位版本程序,就是使用本产品开发。 FOXPROX.EXE 是 Foxpro 的32位版,一个文件即可完美运行所有的 Foxpro 功能。 TNT DOS-...
  • rustc-hash在rustc中使用快速哈希算法。...这与Firefox使用算法相同-Firefox是一种本地化算法,不基于任何广为人知算法-尽管经过修改可生成64位哈希值而不是32位哈希值。 它始终优于rus中基于FNV哈希
  • C/C++中,整型的长度跟编译器相关,编译器的实现取决于... 比如TC++是DOS16下的应用程序,DOS16是16的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32.  C99标准定义一个叫着的头文件

    From: http://blog.csdn.net/s04023083/article/details/5182604

    在C/C++中,整型的长度跟编译器相关,编译器的实现取决于CPU. 比如TC++是DOS16下的应用程序,DOS16是16位的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32.

        C99标准定义一个叫着<stdint.h>的头文件,该头文件定义了一系列各种类别的整数类型typedef名字。尽管速多C++工具支持该头文件已经有一段时间了,但它尚未正式收录于C++标准,因此,在使用该头文件之前,你应该先阅读你的编译器文档,看看它是否支持该文件。在某些C++ 的编译器中,如GNC,为了能使用C99标准的这些新特性,就在<inttypes.h>头文件中引入了这个文件< stdint.h>.

        字长固定的整型类型

        C99标准在<stdint.h>这个头文件的类型定义中,有一套是字长固定的整型类型:

        int8_t   int16_t   int32_t   int64_t

        与其对应的字长固定的无符号型整型类型有:

        uint8_t   uint16_t   uint32_t   uint64_t

        它们的名字非常直观。例如,int8_t是长度固定为8比特的有符号整型类型,而uint8_t则是字长固定为8比特的无符号型整型类型。当你需要确保在不同的平台上,整型数据的字长固定不变,那么你就可以使用这些typedef名字。允许对期望的性质进行更为详细的描述。例如,有的类型的名字是 int_least8_t,它至少有 8 位,还有 int32_t,它恰好是 32 位。

        C99标准标准保证至少可以访问 8 位、16 位、32 位和 64 位类型。没有保证会提供精确宽度类型。不要使用这种类型,除非您肯定是实在不能接受更大的类型。另一个可选的类型是新的 intptr_t 类型,它是一个足够大的可以容纳一个指针的整数。并不是所有的系统都提供这样一种类型(尽管当前所有的 Linux 和 BSD 实现都提供)。

        字长最小的快速整型类型

        该头文件还定义了另外一套typedef名字,即“最小指定长度的快速整数类型”。这套typedef名字中的每一种都表示一种整数类型,它满足在长度不小于某个指定长度的前提下,拥有最快的处理速度。这些整数类型的名字为int_fastX_t(有符号)或者uint_fastX_t(无符号),其中“X”表示最小指定长度。例如,int_fast32_t指得是字长至少为32比特的快速有符号整型类型。最小字长快速整型类型有:

        int_fast8_t  int_fast16_t  int_fast32_t  int_fast64_t

        对应的无符号整型类型有:

        uint_fast8_t  uint_fast16_t  uint_fast32_t  uint_fast64_t

        什么情况下使用这些typedef名字?

        假设你需要一个字长不少于16比特的循环计数器,那么你会希望该计数器的类型总是当前计算机CPU最佳操作的整型类型,而int_fast16_t可以保证任何平台上的编译器总是选择字长不少于16比特的最快整型类型。

     #include <inttypes.h>
    for (int_fast16_t n=0; n<30000; ++n)
    {
    //.. do something
    }


        关于整型参数移植

        假如你需要确定容量的整型,那么你应该使用stdint.h或者inttypes.h中定义的类型。

        这些头文件中定义了以下的整数类型:

     int8_t;
    uint8_t;
    int16_t;
    uint16_t;
    int32_t;
    uint32_t;
    int64_t;
    uint64_t;
    int_least8_t;
    uint_least8_t;
    int_least16_t;
    uint_least16_t;
    int_least32_t;
    uint_least32_t;
    int_least64_t;
    uint_least64_t;
    int_fast8_t;
    uint_fast8_t;
    int_fast16_t;
    uint_fast16_t;
    int_fast32_t;
    uint_fast32_t;
    int_fast64_t;
    uint_fast64_t;
    intptr_t;
    uintptr_t;
    intmax_t;
    uintmax_t;


        如果是boost库的用户则比较幸运,因为在boost库中,<cstdint.hpp>这个头文件封装了C99标准<stdint.h>中的整数类型.


    展开全文
  • 比如TC++是DOS16下的应用程序,DOS16是16的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32。 C99标准定义一个叫着的头文件,该头文件定义了一系列各种类别的整数类型typedef名字。尽管速多C++...

    字长与平台无关的整型数据类型 

        在C/C++中,整型的长度跟编译器相关,编译器的实现取决于CPU。 比如TC++是DOS16下的应用程序,DOS16是16位的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32。
        C99标准定义一个叫着的头文件,该头文件定义了一系列各种类别的整数类型typedef名字。尽管速多C++工具支持该头文件已经有一段时间了,但它尚未正式收录于C++标准,因此,在使用该头文件之前,你应该先阅读你的编译器文档,看看它是否支持该文件。在某些C++的编译器中,如GNC,为了能使用C99标准的这些新特性,就在头文件中引入了这个文件.

    字长固定的整型类型

    C99标准在这个头文件的类型定义中,有一套是字长固定的整型类型:

    int8_t     int16_t     int32_t     int64_t

    与其对应的字长固定的无符号型整型类型有:

    uint8_t    uint16_t    uint32_t    uint64_t

    它们的名字非常直观。例如,int8_t是长度固定为8比特的有符号整型类型,而uint8_t则是字长固定为8比特的无符号型整型类型。当你需要确保在不同的平台上,整型数据的字长固定不变,那么你就可以使用这些typedef名字。允许对期望的性质进行更为详细的描述。例如,有的类型的名字是 int_least8_t,它至少有 8 位,还有 int32_t,它恰好是 32 位。

    C99标准标准保证至少可以访问 8 位、16 位、32 位和 64 位类型。没有保证会提供精确宽度类型。不要使用这种类型,除非您肯定是实在不能接受更大的类型。另一个可选的类型是新的 intptr_t 类型,它是一个足够大的可以容纳一个指针的整数。并不是所有的系统都提供这样一种类型(尽管当前所有的 Linux 和 BSD 实现都提供)。


    字长最小的快速整型类型

    该头文件还定义了另外一套typedef名字,即“最小指定长度的快速整数类型”。这套typedef名字中的每一种都表示一种整数类型,它满足在长度不小于某个指定长度的前提下,拥有最快的处理速度。这些整数类型的名字为int_fastX_t(有符号)或者uint_fastX_t(无符号),其中“X”表示最小指定长度。例如,int_fast32_t指得是字长至少为32比特的快速有符号整型类型。最小字长快速整型类型有:

    int_fast8_t  int_fast16_t  int_fast32_t  int_fast64_t

    对应的无符号整型类型有:

    uint_fast8_t  uint_fast16_t  uint_fast32_t  uint_fast64_t


    什么情况下使用这些typedef名字?
    假设你需要一个字长不少于16比特的循环计数器,那么你会希望该计数器的类型总是当前计算机CPU最佳操作的整型类型,而int_fast16_t可以保证任何平台上的编译器总是选择字长不少于16比特的最快整型类型。

    #include
    for (int_fast16_t n=0; n<30000; ++n)
    {
    //.. do something
    }

    ===================================================================

    关于整型参数移植

    假如你需要确定容量的整型,那么你应该使用stdint.h或者inttypes.h中定义的类型.

    这些头文件中定义了以下的整数类型:
    int8_t;
    uint8_t;
    int16_t;
    uint16_t;
    int32_t;
    uint32_t;
    int64_t;
    uint64_t;

    int_least8_t;
    uint_least8_t;
    int_least16_t;
    uint_least16_t;
    int_least32_t;
    uint_least32_t;
    int_least64_t;
    uint_least64_t;

    int_fast8_t;
    uint_fast8_t;
    int_fast16_t;
    uint_fast16_t;
    int_fast32_t;
    uint_fast32_t;
    int_fast64_t;
    uint_fast64_t;

    intptr_t;
    uintptr_t;

    intmax_t;
    uintmax_t;


    如果是boost库的用户则比较幸运,因为在boost库中,这个头文件封装了C99标准中的整数类型.

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/roger_77/archive/2006/04/13/661859.aspx

    转载于:https://www.cnblogs.com/zhihaowang/archive/2010/03/25/10128680.html

    展开全文
  • 比如TC++是DOS16下的应用程序,DOS16是16的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32。 C99标准定义一个叫着的头文件,该头文件定义了一系列各种类别的整数类型typedef名字。尽管速多C++...
  •  1996 2.0 以32位编译器为核心,支持C/S数据库开发  1997 3.0 语法:加入接口(Interface)机制。IDE:首次提供了(Code Insight)  1998 4.0 语法:加入动态数组和方法覆盖等支持。IDE:增强调试能力,提供代码...
  • 关于这个项目 ...x86-16位C编译器 x86汇编程序 与MS-DOS兼容操作系统 该示例程序是在假定它将以x86实模式启动前提编写。因此,需要以实模式或兼容OS运行MS-DOS。 例如,可以使用以下OS。 x86-16
  • TASM编程工具

    2011-10-09 13:52:52
    到目前为止,TASM最后一个版本是5.0版,这个版本支持WIN32编程,并单独为WIN32编程附带有一整套32位程序:32位的编译器TASM32.EXE、连接器TLINK32.EXE和资源编译器BRC32.EXE。与这些32位程序对应16位工具在...
  • 比如TC++是DOS16下的应用程序,DOS16是16的操作系统,所以TC++中sizeof(int)==16;同理win32中sizeof(int)==32.  C99标准定义一个叫着的头文件,该头文件定义了一系列各种类别的整数类型typedef名字。...
  • C++ 中删除文件方法

    千次阅读 2013-12-06 10:35:39
    方法一:在Windows可以调用DOS命令 #include void main() { system("del C:\\test.dat");...方法二:Windows中如果使用32位编译器,可以使用 Windows API DeleteFile BOOL DeleteFile(LPCTSTR lpFileName);//lpFileN
  • DJGPP下调用中断方法

    千次阅读 2005-04-07 22:11:00
    DJGPP是DOS下完整的32位C/C++保护模式的编译器,运行于386以上机器。DJGPP有一个好帮手叫作Allegro,它是个图形/声音编程库,功能非常强大,应用于界面编程非常方便。可以Allegro编程库编写程序,然后用DJGPP编译...

空空如也

空空如也

1 2 3 4
收藏数 69
精华内容 27
关键字:

dos下的32位c编译器