__ctype_b_loc 它的目的是什么?

问题描述 投票:0回答:3

我试图理解一段使用

__ctype_b_loc()
的代码,问题是我不知道这个函数的目的是什么。

到目前为止,我发现它是在

ctype.h
中定义的。我还找到了它的原型和实现。我仍然不知道这个功能是干什么用的。

有人可以启发我吗?

reverse-engineering glibc
3个回答
23
投票

经过公平的研究,我想我可以自己回答这个问题。

unsigned short int** __ctype_b_loc (void)

是一个函数,它返回指向“traits”表的指针,该表包含一些与每个单个字符的特征相关的标志。

这是带有标志的枚举:

来自
ctype.h

enum
{
  _ISupper = _ISbit (0),        /* UPPERCASE.  */
  _ISlower = _ISbit (1),        /* lowercase.  */
  _ISalpha = _ISbit (2),        /* Alphabetic.  */
  _ISdigit = _ISbit (3),        /* Numeric.  */
  _ISxdigit = _ISbit (4),       /* Hexadecimal numeric.  */
  _ISspace = _ISbit (5),        /* Whitespace.  */
  _ISprint = _ISbit (6),        /* Printing.  */
  _ISgraph = _ISbit (7),        /* Graphical.  */
  _ISblank = _ISbit (8),        /* Blank (usually SPC and TAB).  */
  _IScntrl = _ISbit (9),        /* Control character.  */
  _ISpunct = _ISbit (10),       /* Punctuation.  */
  _ISalnum = _ISbit (11)        /* Alphanumeric.  */
};

举个例子,如果你查找表

__ctype_b_loc()
返回ascii码为
0x30
('
0
')的字符,你将有
0x08d8
.

0x08d8=0000 1000 1101 1000 (Alphanumeric, Graphical, Printing, Hexadecimal, Numeric)

该表与机器上安装的区域设置

localchar
相关联,因此与您系统上的结果相比,该示例可能不准确。


17
投票

Alessandro 自己的回答非常有用,但我想补充一些信息。

如 Alessandro 所述,

__ctype_b_loc(void)
函数返回一个数组,其中每个元素包含一个 ASCII 字符的特征。例如,通过查找表格,我们可以了解到字符“A”是大写的、十六进制的、图形的、打印的、字母数字的。

准确地说,

__ctype_b_loc()
函数返回一个
const unsigned short int**
,它是一个指向384个
unsigned short int*
的数组的指针。 有 ara 384 个元素的原因是表格可以通过以下方式索引:

  • 任何
    unsigned char
    值[0,255](所以256个元素)
  • EOF (-1)
  • any
    signed char
    值 [-128,-1) (所以 127 个元素)

此表由函数使用:

  • 更慢
  • isalpha
  • 正点
  • ...

但是这些函数被定义为宏,所以你永远不会看到它们在汇编代码中被调用。您将看到调用

__ctype_b_loc()
来获取表格,一些代码来检索正确的条目,以及使用位掩码来查看我们正在检查的属性是否已设置。例如,如果我们想查看一个字符是否为大写,我们必须检查位 0 是否已设置。

这里是调用

isupper('A');
生成的汇编代码:

call sym.imp.__ctype_b_loc  ; isupper('A');
mov rax, qword [rax]        ; get the pointer to the array of 'unsigned short int*'
movsx rdx, byte 0x41        ; prepare to look up for character 'A'
add rdx, rdx                ; each entry is 2 bytes, so we double the value of 'A'
add rax, rdx                ; look up for 'A' in the table
movzx eax, word [rax]       ; get the 'unsigned short int' containing the properties
movzx eax, ax               
and eax, 0x100              ; 0x0100 in little-endian is 0x0001 in big-endian (check if bit 0 is set)

0
投票

享受吧! [然后喜欢/投票!]

const short unsigned int** __ctype_b_loc()
{
    static short unsigned int** ret = 0;
    if (ret != 0)
    {
        return (const short unsigned int**)ret;
    }
    int len = sizeof(ctype_b_values)/sizeof(short unsigned int);
    int i;
    short unsigned int* lookupTable = (short unsigned int*)malloc(len*sizeof(short unsigned int));
    for (i = 0; i < len; i++)
    {
        lookupTable[i] = ctype_b_values[i];
    }
    ret = (short unsigned int**)malloc(sizeof(short unsigned int*));
    *ret = lookupTable;
    return (const short unsigned int**)ret;
}

short unsigned int ctype_b_values[]={
0x0002, // 
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x2003, //  
0x2002, //
0x2002, //
0x2002, //
0x2002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, 
0x0002, 
0x0002, 
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x0002, //
0x6001, // 
0xc004, //!
0xc004, //"
0xc004, //#
0xc004, //$
0xc004, //%
0xc004, //&
0xc004, //'
0xc004, //(
0xc004, //)
0xc004, //*
0xc004, //+
0xc004, //,
0xc004, //-
0xc004, //.
0xc004, ///
0xd808, //0
0xd808, //1
0xd808, //2
0xd808, //3
0xd808, //4
0xd808, //5
0xd808, //6
0xd808, //7
0xd808, //8
0xd808, //9
0xc004, //:
0xc004, //;
0xc004, //<
0xc004, //=
0xc004, //>
0xc004, //?
0xc004, //@
0xd508, //A
0xd508, //B
0xd508, //C
0xd508, //D
0xd508, //E
0xd508, //F
0xc508, //G
0xc508, //H
0xc508, //I
0xc508, //J
0xc508, //K
0xc508, //L
0xc508, //M
0xc508, //N
0xc508, //O
0xc508, //P
0xc508, //Q
0xc508, //R
0xc508, //S
0xc508, //T
0xc508, //U
0xc508, //V
0xc508, //W
0xc508, //X
0xc508, //Y
0xc508, //Z
0xc004, //[
0xc004, //
0xc004, //]
0xc004, //^
0xc004, //_
0xc004, //`
0xd608, //a
0xd608, //b
0xd608, //c
0xd608, //d
0xd608, //e
0xd608, //f
0xc608, //g
0xc608, //h
0xc608, //i
0xc608, //j
0xc608, //k
0xc608, //l
0xc608, //m
0xc608, //n
0xc608, //o
0xc608, //p
0xc608, //q
0xc608, //r
0xc608, //s
0xc608, //t
0xc608, //u
0xc608, //v
0xc608, //w
0xc608, //x
0xc608, //y
0xc608, //z
0xc004, //{
0xc004, //|
0xc004, //}
0xc004, //~
0x0002, //
0x0000, //€
0x0000, //
0x0000, //‚
0x0000, //ƒ
0x0000, //„
0x0000, //…
0x0000, //†
0x0000, //‡
0x0000, //ˆ
0x0000, //‰
0x0000, //Š
0x0000, //‹
0x0000, //Œ
0x0000, //
0x0000, //Ž
0x0000, //
0x0000, //
0x0000, //‘
0x0000, //’
0x0000, //“
0x0000, //”
0x0000, //•
0x0000, //–
0x0000, //—
0x0000, //˜
0x0000, //™
0x0000, //š
0x0000, //›
0x0000, //œ
0x0000, //
0x0000, //ž
0x0000, //Ÿ
0x0000, // 
0x0000, //¡
0x0000, //¢
0x0000, //£
0x0000, //¤
0x0000, //¥
0x0000, //¦
0x0000, //§
0x0000, //¨
0x0000, //©
0x0000, //ª
0x0000, //«
0x0000, //¬
0x0000, //­
0x0000, //®
0x0000, //¯
0x0000, //°
0x0000, //±
0x0000, //²
0x0000, //³
0x0000, //´
0x0000, //µ
0x0000, //¶
0x0000, //·
0x0000, //¸
0x0000, //¹
0x0000, //º
0x0000, //»
0x0000, //¼
0x0000, //½
0x0000, //¾
0x0000, //¿
0x0000, //À
0x0000, //Á
0x0000, //Â
0x0000, //Ã
0x0000, //Ä
0x0000, //Å
0x0000, //Æ
0x0000, //Ç
0x0000, //È
0x0000, //É
0x0000, //Ê
0x0000, //Ë
0x0000, //Ì
0x0000, //Í
0x0000, //Î
0x0000, //Ï
0x0000, //Ð
0x0000, //Ñ
0x0000, //Ò
0x0000, //Ó
0x0000, //Ô
0x0000, //Õ
0x0000, //Ö
0x0000, //×
0x0000, //Ø
0x0000, //Ù
0x0000, //Ú
0x0000, //Û
0x0000, //Ü
0x0000, //Ý
0x0000, //Þ
0x0000, //ß
0x0000, //à
0x0000, //á
0x0000, //â
0x0000, //ã
0x0000, //ä
0x0000, //å
0x0000, //æ
0x0000, //ç
0x0000, //è
0x0000, //é
0x0000, //ê
0x0000, //ë
0x0000, //ì
0x0000, //í
0x0000, //î
0x0000, //ï
0x0000, //ð
0x0000, //ñ
0x0000, //ò
0x0000, //ó
0x0000, //ô
0x0000, //õ
0x0000, //ö
0x0000, //÷
0x0000, //ø
0x0000, //ù
0x0000, //ú
0x0000, //û
0x0000, //ü
0x0000, //ý
0x0000, //þ
0x0000, //ÿ
0x0020, // 
0x0000, //
0x0000, //
0x0000, //
0x0000, //
0x0000, //
0x0028, //
0x0000, //
0x0043, //
0x0000, //  
0x0029, //
0x0000, //
0x0000, //
0x0000,
0x0000, //
0x0000, //
0x003c, //
0x0000, //
0x003c, //
0x0000, //
0x0000, //
0x0000, //
0x0000, //
0x0000, 
0x002d, 
0x0000, 
0x0000, 
0x0000, 
0x0000, 
0x0000, //
0x0028, //
0x0000, //
0x0052, // 
0x0000, //!
0x0029, //"
0x0000, //#
0x0000, //$
0x0000, //%
0x0000, //&
0x0000, //'
0x0075, //(
0x0000, //)
0x0000, //*
0x0000, //+
0x0000, //,
0x0000, //-
0x002c, //.
0x0000, ///
0x0000, //0
0x0000, //1
0x0000, //2
0x0000, //3
0x003e, //4
0x0000, //5
0x003e, //6
0x0000, //7
0x0000, //8
0x0000, //9
0x0000, //:
0x0000, //;
0x0020, //<
0x0000, //=
0x0031, //>
0x0000, //?
0x002f, //@
0x0000, //A
0x0034, //B
0x0000, //C
0x0020, //D
0x0000, //E
0x0000, //F
0x0000, //G
0x0000, //H
0x0000, //I
0x0020, //J
0x0000, //K
0x0031, //L
0x0000, //M
0x002f, //N
0x0000, //O
0x0032, //P
0x0000, //Q
0x0020, //R
0x0000, //S
0x0000, //T
0x0000, //U
0x0000, //V
0x0000, //W
0x0020, //X
0x0000, //Y
0x0033, //Z
0x0000, //[
0x002f, 
0x0000, //]
0x0034, //^
0x0000, //_
0x0020, //`
0x0000, //a
0x0000, //b
0x0000, //c
0x0000, //d
0x0000, //e
0x0041, //f
0x0000, //g
0x0045, //h
0x0000, //i
0x0000, //j
0x0000, //k
0x0000, //l
0x0000, //m
0x0078, //n
0x0000, //o
0x0000, //p
0x0000, //q
0x0000, //r
0x0000, //s
0x0073, //t
0x0000, //u
0x0073, //v
0x0000, //w
0x0000, //x
0x0000, //y
0x0000, //z
0x0000, //{
0x0061, //|
0x0000, //}
0x0065, //~
0x0000, //
};
© www.soinside.com 2019 - 2024. All rights reserved.