-2

Like in the title said the asm programm should not automatically break a new line after executing it. My programm is a simplified version of the "echo" command in linux. It prints the arguments given by the user. If the users first argument is '-n' the prompt should be to the right of the output and not break the line. So my question is how do i force NOT breaking a line in AT&T after executing?

.code32
.section .data
    lf: .ascii "-n"             # Lf = line feed
    withoutLF: .long 0             # helper flag
    counter: .long 0            # is the counter of bytes of an argument
    arguments: .long 0          # number of arguments
    white_space: .ascii " "     # is white space

.section .text

.globl _start

_start:
    movl (%esp), %esi           # gets the argument count of the stack to ESI
    movl %esi, arguments        # moves argument count to arguments variable
    decl arguments              # decrement counter
    addl $8, %esp               # move the esp to the actual arguments

    ### check if first argument is '-n' ###

    movl (%esp), %esi           # move first string to ESI
    movl $lf, %edi              # move second string to EDI
    movl $2, %ecx               # number of  bytes which should be compared
    cld                         # clear Flag D, wihtout clearance the compare ill occur in inverse order 
    rep cmpsb                   # the actual comparing of the 2 strings
    jz _without_lf              # if the same jump to _without_lf

_arg:
    movl (%esp), %esi           # moves argument of stack to ESI
    cmpl $0, arguments          # compares if there any arguments left
    je _exit                    # out of arguments --> exit progamm
    jmp _print_white_space      # if NOT out of arguments --> print a white space


_numberOfBytes:
    lodsb                       # load string in bytes from ESI --> saves byte in EAX
    cmpb $0, %al                # compare if byte is equal 0
    je _print_arg               # jumps to section to print the actual argument
    incl counter                # increment the counter (number of bytes)
    jmp _numberOfBytes          # jump to the beginning of _numberOfBytes (to read the left bytes)

_print_arg:
    movl counter, %edx          # EDX message length 
    movl $1, %ebx               # EBX = file descriptor (1 = stdout)
    movl (%esp), %ecx           # ECX = address of message
    movl $4, %eax               # syscall number (4 = write)
    int $0x80                   # call kernel by interrupt

    addl $4, %esp               # move ESP to next argument (1 argument = 4 bytes)
    decl arguments              # decrement the number of arguments
    movl $0, counter            # reset the counter of bytes
    jmp _arg                    # jump to the top of _arg

_print_white_space:
    movl $1, %edx               # EDX message length
    movl $1, %ebx               # EBX = file descriptor (1 = stdout)
    movl $white_space, %ecx     # ECX = address of message (startaddress)
    movl $4, %eax               # syscall number (4 = write)
    int $0x80                   # call kernel by interrupt
    jmp _numberOfBytes          # jump to _numberOfBytes --> still arguments left to print

_without_lf:
    addl $4, %esp               # move ESP to next argument of the stack
    decl arguments              # decrement arguments counter --> '-n' is not counted, just used
    incl withoutLF              # move 1 to withLF (helper flag)
    jmp _arg

   _exit:                       # exit the program
     movl $0, %ebx
     movl $1, %eax
     int $0x80

Here is the output of my program

Here is the output of my program

Output of $PS1, $PS1 and the normal echo command:

enter image description here

Count of bytes is 6 of the word "Hello" so with a null termination

Count of bytes

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
plako
  • 11
  • 2
  • 3
    plako is a new contributor. So please explain why you downvote before doing so. Is it because he didn't explain what he tried, or a remark that it would be easier to solve with an example (like `date`). – Walter A Jan 12 '20 at 14:17
  • 1
    The shell does not automatically print a newline after your program end (unlike the DOS shell). So if you don't want a newline, then don't print one. – fuz Jan 12 '20 at 14:38
  • As @prl commented on an answer: if you don't want a line-feed in the output of your program, don't print or `write` one to stdout. Otherwise (without `-n`), *do* print one yourself, after the args. If that's what you were already trying to do, put an [mcve] of your code in the question if you're stuck debugging it. – Peter Cordes Jan 12 '20 at 14:39
  • Now i added the code (with the output) I am currenly working with and my first assumption is that in the section _exit something prints a line feed. – plako Jan 12 '20 at 15:08
  • @plako What operating system are you programming for? What commands do you type to assemble and link your code? – fuz Jan 12 '20 at 16:26
  • 3
    Your code does work correctly on my system and does not print a newline. It is possible that you have some script in your shell that adds a newline before printing a prompt if the previous command did not end with the cursor at the beginning of a line. I advise you to disable such scripts when testing your code. – fuz Jan 12 '20 at 16:30
  • 1
    At the shell prompt can you show use the output of `echo $PS1` and `echo $PS2` – Michael Petch Jan 12 '20 at 16:43
  • 2
    What happens on your system if you run `/bin/echo -n foo`? (Or shell-builtin `echo -n` or `printf foo`, if those don't get special cased by your shell's newline-fixup). It is possible for the shell to determine cursor position with an ioctl or escape code. – Peter Cordes Jan 13 '20 at 07:57
  • @PeterCordes i am using Arch Linux (64 bit) and use following commands to create the .o file: as -32 echo.s -o echo.o ld -melf_i386 echo.o -o echo – plako Jan 13 '20 at 10:14
  • 1
    Ok good, but what happens if you use `/bin/echo -n foo` which we know definitely works. Also you can use `strace ./echo -n foo` to check whether your program prints a newline or not. If not, then @fuz is right and your shell is "fixing" the cursor position for you after your program leaves it at the end of a line. – Peter Cordes Jan 13 '20 at 18:30
  • @PeterCordes i updated my post with the output of the bin/echo command. – plako Jan 15 '20 at 18:07
  • 1
    Peter wants to see the output of `/bin/echo -n foo` not your version `./echo`. He also wants to see the output of the command `strace ./echo -n foo` to see the system calls and the parameters. I asked you for the output of `echo $PS1` and `echo $PS2` to see what the shell prompt you were using was. – Michael Petch Jan 15 '20 at 20:39
  • As you can see, your shell (`fish`) moves the cursor even after `/bin/echo -n`. Your implementation is (presumably) correct; you can also check it with `./echo -n` | hexdump -C`. Or actually install `strace` - it's a vital tool for debugging the system calls that any program makes. – Peter Cordes Jan 16 '20 at 07:36
  • So is there any way to fix this in my shell? Or a special way to handle this scenario? – plako Jan 16 '20 at 08:03
  • I'm voting to close this question as off-topic because it has been established this isn't a programming problem (the issue is not the code) but how the `fish` shell behaves. – Michael Petch Jan 16 '20 at 17:06

1 Answers1

2

Your program is working.

Like zsh, fish does a trick to get your prompt onto a new line after a programs output, even if it doesn't end in a newline.

When that happens, a "⏎" is left at the end of the line. (zsh leaves a "%" IIRC)

So those times that you can see a "⏎", your program already didn't print a newline. But to avoid confusion between the program's output and the shell's prompt, it's nice to always have the prompt on a new line, so this trick is used.

And fish doesn't use $PS1 or $PS2, so those are useless to show. Instead it uses the fish_prompt function.

faho
  • 14,470
  • 2
  • 37
  • 47