flat assembler
Message board for the users of flat assembler.

Index > Linux > String Interpolation

Author
Thread Post new topic Reply to topic
asmblr_88



Joined: 12 Jan 2023
Posts: 12
asmblr_88 17 Jun 2023, 17:08
Hello, all.

I have been trying to write a program using fasm to take in user input, and respond with the user's name.

EXAMPLE:

The Computer: What is your name?
The User: John
The Computer: Hello, John!
It was nice to meet you, I must go now, bye!

It works, however I cannot get it to print a period or an exclamation mark at the end of the response to the user.

It just ends up like this:

Hello, John

I have tried bumping up the byte count in rdx bye one or two but it only ends up adding a newline or linefeed after the name in the response.

I cannot trail a period into the input stream of the response?

I appreciate anyone who can help me with this conundrum.

I will post the code in the thread.

I hope everyone has a great day!


Description:
Download
Filename: string_interpolation.asm
Filesize: 3.28 KB
Downloaded: 103 Time(s)


_________________
asmblr_88
Post 17 Jun 2023, 17:08
View user's profile Send private message Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 417
Location: Australia
redsock 17 Jun 2023, 20:59
There are several issues with your code, probably the most significant is highlighted with your comments. syscall numbers go in eax, with arguments in rdi, rsi, rdx, r10, r8, r9 and always return in rax/eax.

So for a read (2) syscall: fd into edi, buf into rsi, length into rdx
and for write (2) syscall: fd into edi, buf into rsi, count into rdx

You can see from the following two excerpts exactly what your program is doing:
Code:
> echo test | ./string_interpolation | hexdump -C
00000000  57 68 61 74 20 69 73 20  79 6f 75 72 20 6e 61 6d  |What is your nam|
00000010  65 3f 20 48 65 6c 6c 6f  2c 20 74 65 73 74 0a 00  |e? Hello, test..|
00000020  00 00 00 00 00 00 2e 0a  49 74 20 77 61 73 20 6e  |........It was n|
00000030  69 63 65 20 74 6f 20 6d  65 65 74 20 79 6f 75 2c  |ice to meet you,|
00000040  20 49 20 6d 75 73 74 20  67 6f 20 6e 6f 77 2e 20  | I must go now. |
00000050  42 79 65 21 0a                                    |Bye!.|
00000055
    
and
Code:
> echo test | strace ./string_interpolation >/dev/null
execve("./string_interpolation", ["./string_interpolation"], 0x7ffcaacb68d0 /* 78 vars */) = 0
write(1, "What is your name? ", 19)     = 19
read(0, "test\n", 12)                   = 5
write(1, "Hello, ", 7)                  = 7
write(1, "test\n\0\0\0\0\0\0\0", 12)    = 12
write(1, ".\n", 2)                      = 2
write(1, "It was nice to meet you, I must "..., 45) = 45
exit(0)                                 = ?
+++ exited with 0 +++
    
Smile Hope this helps
Post 17 Jun 2023, 20:59
View user's profile Send private message Reply with quote
asmblr_88



Joined: 12 Jan 2023
Posts: 12
asmblr_88 18 Jun 2023, 07:54
I am not completely familiar with using hexdump or strace, so I will study up more on how to use it and hopefully I will understand this better.

Thank's a lot redsock! Much appreciated!

I hope you have a great day.
Post 18 Jun 2023, 07:54
View user's profile Send private message Reply with quote
Flier-Mate



Joined: 26 May 2023
Posts: 88
Flier-Mate 18 Jun 2023, 11:42
I refer to hexdump by redsock:
Code:
00000000  57 68 61 74 20 69 73 20  79 6f 75 72 20 6e 61 6d  |What is your nam|
00000010  65 3f 20 48 65 6c 6c 6f  2c 20 74 65 73 74 0a 00  |e? Hello, test..|
00000020  00 00 00 00 00 00 2e 0a  49 74 20 77 61 73 20 6e  |........It was n|    


It is because a linefeed character is appended to the input buffer (name). So if user enters a name less than 12 chars, you will print 0xa (linefeed) as well carried from the input buffer.

The hexdump above : "Hello, test", immediately followed by one linefeed (0xa), and seven null chars (0x), so 4 ("test") + 1 (linefeed) + 7 (null) made up 12 bytes.

Now if you type "123456789012" as the input name, you will get the result you want, because 12 bytes could not contain 13th char which is linefeed.

The key is, remove the linefeed (0xa) character after the name, will likely solve you problem. Embarassed
Post 18 Jun 2023, 11:42
View user's profile Send private message Reply with quote
asmblr_88



Joined: 12 Jan 2023
Posts: 12
asmblr_88 18 Jun 2023, 21:09
I applied your advice, and it worked. My brain is still trying to comprehend it.

Studying the hexdump also helped a lot as well.

Since I am not using a constant that counts characters automatically (such as $-input_name), I have to know the exact number of characters I will be inputting when prompted.

Since I put John, and John is 4 characters, I reserved 4 bytes for the response variable and it allows a period at the end.
But I reserved 16 bytes for the name variable, and if I were to type Johnny, it would only print John since I have not written any line to offset it I guess.
I am going to try to implement a macro to see if it works maybe.

I will post the edited version in case anyone needs it for future reference.

Thanks everyone, have a great night!


Description:
Download
Filename: string_interpolation_2.asm
Filesize: 3.28 KB
Downloaded: 91 Time(s)

Post 18 Jun 2023, 21:09
View user's profile Send private message Reply with quote
asmblr_88



Joined: 12 Jan 2023
Posts: 12
asmblr_88 18 Jun 2023, 21:16
Also redsock, I wasn't aware that I could use eax and rax registers in the same program. Is it because rax is an extension of eax?

Also when you say return, do you mean when popping off the stack, putting the exit code in it or the success code?

I will update the program soon when I have the time to follow along with your recommendations of putting each instruction into which registers they belong in.

Thanks again!
Post 18 Jun 2023, 21:16
View user's profile Send private message Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 417
Location: Australia
redsock 18 Jun 2023, 22:52
When you know for certain that you only need 32 bits, it is perfectly safe and sane to use the 32 bit registers in your 64bit program. Things like syscall numbers and file descriptors are guaranteed to be < 32 bits.
Code:
mov eax, 1
xor ecx, ecx    
zero the upper 32 bit dword in rax and rcx respectively.

By "return in rax/eax", I mean syscall returns themselves. Your call to the read syscall returns the number of bytes read and 0 if EOF, or <0 on error (noting EINTR is not really an error but needs to be handled as well). Similarly, your call to the write syscall returns the number of bytes written.
Post 18 Jun 2023, 22:52
View user's profile Send private message Reply with quote
Flier-Mate



Joined: 26 May 2023
Posts: 88
Flier-Mate 18 Jun 2023, 23:38
Assigning syscall number to eax is shorter than to rax.

Code:
0:  48 c7 c0 01 00 00 00    mov    rax,0x1
7:  b8 01 00 00 00          mov    eax,0x1    


2 bytes shorter in the assembled binary.
Post 18 Jun 2023, 23:38
View user's profile Send private message Reply with quote
asmblr_88



Joined: 12 Jan 2023
Posts: 12
asmblr_88 19 Jun 2023, 13:32
I feel like I am learning a lot more incrementally.

Thanks to everyone for your patience and explanations. I appreciate it.

I feel as though I am learning a little bit more on how the processor works, especially when it comes to processing information as a stream of bytes. It makes me appreciate and understand just how fast the processor is working. It is helping me to visualize it more easily than before.

_________________
asmblr_88
Post 19 Jun 2023, 13:32
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.