简体   繁体   中英

Manually Add Newline To Stack Variable In x86 Linux Assembly

I wrote a simple assembly program that gets two integers from the user via a prompt, multiplies them together and prints that out. I wanted to do this directly with sys_read and not scanf so I could manually convert the input to an integer after removing the LF .

Here's the full source: http://pastebin.com/utnjTvNZ

In particular, what I want to do now is manually add a newline to the result of the multiplication that is now converted back to it's ASCII char equivalent. Initially, I thought I could just left shift 16 bits and add 0xA leaving me with, for example, 0x0034000A on the stack for 2*2 (0x0034 is "4" in ASCII chars) , followed by a null terminator and a LF . However, the LF is printing before the result. I figured this was an endianess thing, so I tried the reverse (0x000A0034) and that just printed some other ASCII char instead.

So, simply, how do I properly push a newline to the stack so that this is printed with a newline following the number when using sys_write ? What I'm missing is how strings are stored on the stack... which I can't test because normally you just create a variable and push the address onto the stack.

I'm aware some things in here could be done better, cleaner and up-to-standards and whatnot. I understand things intuitively so it's something I just need to do to better understand the stack and Linux system calls in general.

Okay, so to answer my own question thanks to the help of Jester , to add a newline to the 32-bit word I was displaying in memory, I had to understand endianness. Since I compiled for 32-bit, my program is functioning on 32-bit words. These words' bytes are written into memory "backwards". The words themselves are still stored in "normal" order. For example 0x0A290028 0x0A293928 prints (NULL)LF(9)LF. The bytes are backwards but the words are not. Sys_write, since it just uses a void *buf and isn't aware of strings, just reads bytes in endian-order from the buffer and spits them out.

What I was able to do was simply left-shift my single-digit product, for example, 0x00000034 by 8-bits. This left me with 0x00003400. To that, I could add 0x000A0000. This would result in 0x000A3400, and the number "4" being printed followed by a newline.

So, the new procedure looks like this:

multprint:
    mov eax, sys_write ;4
    mov ebx, stdout    ;1
    mov ecx, resultstr
    mov edx, resultstrLen
    dec edx
    int 0x80

    pop eax     ;multiplican't
    pop ebx     ;multiplicand
    mul ebx
    add eax, '0'

    shl eax, 8 ;make room for () and LF
    add eax, 0x0A290028

    push eax

    mov ecx, esp
    ;mov [num], eax ;use these two lines if I don't want to use the stack
    ;mov ecx, num 

    mov eax, sys_write
    mov ebx, stdout
    mov edx, 4
    int 0x80

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM