2

I am trying to call isdigit, and to do so I need first byte of my buffer, which is defined as following.

...

.equ ARRAYSIZE, 20

    .section ".bss"
buffer:
    .skip ARRAYSIZE

...

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

Thus, buffer is allocated a memory space of 20 byte and I put some value using scanf, as shown in input.

Now I want to access the first 4 bytes in order to call isdigit. How can I access them?

My initial guess is to use movl buffer, %eax, since eax register is 4 byte-size, and will store the first 4 bytes in buffer. But I am not sure this is how it works.

Please let me know if I can only access the first 4 bytes of buffer, or any other methods to apply isdigit to those first 4 bytes. Thank you.

2
  • Normally .section .bss wouldn't have quotes around ".bss". I'm not sure that even works. Commented May 19, 2019 at 16:38
  • 2
    libc / POSIX isdigit is locale-aware, but if you can assume that the current locale's only "digit" characters are '0' .. '9' then it's much more efficient to manually check with sub $'0', %al / cmp $10, %al / jae not_a_digit Commented May 19, 2019 at 19:22

1 Answer 1

2

You will want to apply isdigit to those 4 bytes separately. You can fetch them from the buffer one by one using a loop that does 4 iterations. The counter is setup in the %ecx register and a pointer to the buffer is setup in the %esi register.

    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

Alternatively

    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
Sign up to request clarification or add additional context in comments.

4 Comments

libc isdigit(3) takes its arg on the stack, in the i386 System V calling convention. And its arg is an int, so you should be sign-extending your byte. Also, probably most sensible to assume that buffer holds a 0-terminated string because it was written by scanf.
May I ask why we need to call isdigit for each byte separately? As far as I know, the argument of isdigit should be 4 bytes.
@JimmySuh Your buffer contains a zero-terminated string that you got from scanf. Each byte is just one character for which you want to test if it is a digit. Reading 4 bytes at once would also retrieve 4 characters at once, but isdigit can process just 1 character each time. Sure, the argument of isdigit is a dword, but it has to contain a single character that you want verified. Hence extending the byte into a dword.
Oh now I get it. Thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.