Таблица __ctype_b и ее использование - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть этот фрагмент кода asm, который использует массив __ctype_b, я пытаюсь понять, что это такое, кто-нибудь знает, что он делает?

ps: я знаю, что такое __ctype_b_loc (), эторазные.

mov     eax, [rbp+counter]
cdqe
add     rax, [rbp+server_received_buffer]
movzx   eax, byte ptr [rax]
movsx   rax, al
add     rax, rax
mov     rdx, rax
mov     rax, cs:__ctype_b
lea     rax, [rdx+rax]
movzx   eax, word ptr [rax]
movzx   eax, ax
and     eax, 20h
test    eax, eax

1 Ответ

0 голосов
/ 23 ноября 2018

Я нашел ответ.__ctype_b - это массив, который будет использоваться в макросе "__isctype_l":

#  define __isctype_l(c, type, locale) \
  ((locale)->__ctype_b[(int) (c)] & (unsigned short int) type)

, и он используется здесь:

#  define __isalnum_l(c,l)  __isctype_l((c), _ISalnum, (l))
#  define __isalpha_l(c,l)  __isctype_l((c), _ISalpha, (l))
#  define __iscntrl_l(c,l)  __isctype_l((c), _IScntrl, (l))
#  define __isdigit_l(c,l)  __isctype_l((c), _ISdigit, (l))
#  define __islower_l(c,l)  __isctype_l((c), _ISlower, (l))
#  define __isgraph_l(c,l)  __isctype_l((c), _ISgraph, (l))
#  define __isprint_l(c,l)  __isctype_l((c), _ISprint, (l))
#  define __ispunct_l(c,l)  __isctype_l((c), _ISpunct, (l))
#  define __isspace_l(c,l)  __isctype_l((c), _ISspace, (l))
#  define __isupper_l(c,l)  __isctype_l((c), _ISupper, (l))
#  define __isxdigit_l(c,l) __isctype_l((c), _ISxdigit, (l))
#  define __isblank_l(c,l)  __isctype_l((c), _ISblank, (l))

, тогда мы достигнем этого перечисления

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.  */
};

теперь нам нужно понять, что означает 0x20 из определения _ISbit

# if __BYTE_ORDER == __BIG_ENDIAN
#  define _ISbit(bit)   (1 << (bit))
# else /* __BYTE_ORDER == __LITTLE_ENDIAN */
#  define _ISbit(bit)   ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
# endif

0x20: 0010 0000

из кода asm, я знаю, что это big endian.поэтому номер сдвига должен быть 5, и это пробел.

Вывод: этот код asm находит пробел из server_received_buffer

...