Question

I am trying to learn some very basic ASM, in order to help me with reading gdb output figuring out stuff. I have been following a few tutorials online, and have come across something I can't figure out how to do.

The tutorial I am following (http://programminggroundup.blogspot.fr/2007/01/programming-from-ground-up.html) talks about string IO in chapter 5. It uses the .bss segment to declare a 500-length array for the input. I can get this to work no problem. However, I'm now trying to have the array on the stack, rather than in the .bss segment (which seems like 'global memory' to me).

The problem is, I can't figure out what I'm doing wrong. As far as I can see here, I have moved a 64-byte section on the stack that I am trying to use to hold the input, and then output it. The code doesn't core or otherwise expode, but when I run it and type "Hello" (without quotes) then the result is "ello", written in the next command-line. It is followed by a return-of-line, thus the 'ello' is immediately executed upon termination of the program.

user_omitted@serveromitted:~/folderomitted>./basic_io
Hello
user_omitted@serveromitted:~/folderomitted>ello

As far as I can see here, I'm writing to the stack. I would expect that I don't need to zero it, as the input should overwrite the content correctly. Am I doing something insanely wrong here?

This is using a unix IA-64 system with gas. Additionally, if I am doing stuff that's really dumb (not just related to the issue I have), please tell me!

.section .text
.globl _start
_start:
    pushq %rbp # Store the original base pointer on the stack
    mov %rsp, %rbp # The new base pointer is targeting the start of the stack
    sub $64, %rsp # Move the stack pointer down by 64 bytes, thus saying we have 64 bytes to play with
    mov %rsp, %rcx # Pass the content of the stack pointer to rcx, for the system call
    mov $64, %rdx # Store the length of the buffer
    mov $3, %rax # State that we want to use system_read 
    mov $0, %rbx # Select the handler (STDIN)
    int $0x80 # invoke


    mov $4, %rax # system_write
    mov $1, %rbx # STDOUT
    mov $64, %rdx # length of buffer
    mov %rsp, %rcx # location of the buffer on the stack
    int $0x80 # invoke

    mov %rbp, %rsp # Restore the stack pointer to the original location
    popq %rbp # pop the base pointer off the stack

    mov $1, %rax # sys_exit
    mov $0, %rbx # return code
    int $0x80 # invoke
Was it helpful?

Solution

This looks like the same issue:

Linux write sys call using string on stack

Disclaimer: I am running 32-bit hardware and have no experience with 64-bit code. It "might" be a mistake to use a 32-bit reference (Jon Bartlett's excellent PGU!) for 64-bit code. As indicated in the link above (and on the right), you're using 32-bit system call numbers, putting the parameters in registers suitable for 32-bit code, and using the 32-bit int 0x80. I'm told that this works (still), and you confirm that it works with buffer in .bss. I think that %rsp is "too high", as indicated in the link.

In any case, sys_read does not return a zero-terminated string, and sys_write wouldn't pay any attention to it if it did. sys_write writes the number of bytes in %edx (%rdx) regardless of whether it's "garbage" or not. sys_read returns the number of bytes actually entered in %eax (%rax), and this is what you want to put in %edx (%rdx) (same register for 32- or 64-bit code in this case) for the sys_write. This is not your problem, but it's still "wrong".

I've seen this issue of "excess" appearing at the command prompt if the pesky user types more than is allowed in %edx in 32-bit code. It is potentially "dangerous"! It is probably a good idea to "flush the buffer" if necessary. If %eax (%rax) is less than %edx (%rdx), you're okay. If they're equal, check the last byte in the buffer for the linefeed (ascii code 0xa). If it's there, you're okay. If not, keep reading until you find the linefeed. This is probably "overkill" for a toy program where you're the only user, but it's still a good idea to be aware of the issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top