【问题标题】:Accessing the first byte of buffer in assembly?访问汇编中缓冲区的第一个字节?
【发布时间】:2019-05-19 14:11:41
【问题描述】:

我正在尝试调用 isdigit,为此我需要缓冲区的第一个字节,其定义如下。

...

.equ ARRAYSIZE, 20

    .section ".bss"
buffer:
    .skip ARRAYSIZE

...

input:
    pushl $buffer
    pushl $scanFormat
    call  scanf
    addl  $8, %esp

因此,缓冲区被分配了一个 20 字节的内存空间,我使用 scanf 输入了一些值,如输入所示。

现在我想访问前 4 个字节以调用 isdigit。如何访问它们?

我最初的猜测是使用 movl 缓冲区,%eax,因为 eax 寄存器是 4 字节大小,并且会将前 4 个字节存储在缓冲区中。但我不确定它是如何工作的。

如果我只能访问缓冲区的前 4 个字节,或者任何其他将 isdigit 应用于前 4 个字节的方法,请告诉我。谢谢。

【问题讨论】:

  • 通常.section .bss 不会在".bss" 周围加上引号。我不确定这是否有效。
  • libc / POSIX isdigit 是区域设置感知的,但如果您可以假设当前区域设置的唯一“数字”字符是 '0' .. '9',那么它更有效手动检查sub $'0', %al/cmp $10, %al/jae not_a_digit

标签: assembly x86


【解决方案1】:

您需要将 isdigit 分别应用于这 4 个字节。您可以使用执行 4 次迭代的循环从缓冲区中一一获取它们。计数器设置在%ecx 寄存器中,指向缓冲区的指针设置在%esi 寄存器中。

    movl    $4, %ecx          ; Counter
    movl    $buffer, %esi     ; Pointer
More:
    movsbl  (%esi), %eax      ; Get next byte sign-extending it
    push    %eax
    call    isdigit
    addl    $4, %esp
    ...
    incl    %esi              ; Advance the pointer
    decl    %ecx              ; Decrement the counter
    jnz     More              ; Continu while counter not exhausted

或者

    xorl    %esi, %esi        ; Offset start at 0
More:
    movsbl  buffer(%esi), %eax ; Get next byte sign-extending it
    push    %eax
    call    isdigit
    addl    $4, %esp
    ...
    incl    %esi              ; Advance the offset
    cmpl    $4, %esi          ; Test for max offset
    jb      More              ; Continu while offset not max-ed

【讨论】:

  • libc isdigit(3) 在 i386 System V 调用约定中将其 arg 放在堆栈中。它的参数是int,所以你应该对你的字节进行符号扩展。此外,假设buffer 包含一个以 0 结尾的字符串可能是最明智的,因为它是由scanf 编写的。
  • 请问为什么我们需要为每个字节分别调用isdigit?据我所知,isdigit 的参数应该是 4 个字节。
  • @JimmySuh 您的缓冲区包含您从scanf 获得的以零结尾的字符串。每个字节只是一个字符,您要测试它是否是数字。一次读取 4 个字节也将一次检索 4 个字符,但 isdigit 每次只能处理 1 个字符。当然,isdigit 的参数是一个双字,但它必须包含一个您想要验证的字符。因此将字节扩展为双字。
  • 哦,现在我明白了。谢谢。
猜你喜欢
  • 2021-08-29
  • 1970-01-01
  • 2020-03-17
  • 2012-07-07
  • 2022-12-21
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多