ilgaar
ilgaar

Reputation: 844

Why the following assembly code doesn't print out the new line (0xa) character?

In the code below, NASM runs everything as expected, except for printing a new line character at the end. what could be the reason?

%define sys_write       0x2000004           ; system call number for write
%define sys_read        0x2000003           ; system call number for read
%define sys_exit        0x2000001           ; system call number for exit
%define std_out         0x1                 ; file descriptor number for standard output
%define std_in          0x2                 ; file descriptor number for standard input
%define new_line        0xa                 ; a new line character
%define current_address $                   ; address of current location

; a macro to implement the write system call and write
; a string into standard output using two parameters
%macro write_string 2
    mov rax, sys_write                          ; system call to write
    mov rdi, std_out                            ; standard output
    mov rsi, %1                                 ; a string to write
    mov rdx, %2                                 ; length of the string
    syscall                                     ; kernel call interruption
%endmacro

; a macro to implement the exit system call
%macro exit 0
    mov rax, sys_exit                           ; system call to exit
    syscall
%endmacro

    section .data

message:    db 'Displaying 9 stars', new_line       ; a message
.length:    equ current_address - message           ; length of the message
asterisks:  times 9 db '*'                          ; a string of 9 asterisks

global start

    section .text

start:                                      ; linker entry point

    write_string message, message.length    ; print a message to standard output
    write_string asterisks, 9               ; print 9 asterisks
    write_string new_line, 1                ; print a line feed(new line)

    exit                                    ; end the program

after assembling:

user$ nasm -f macho64 9stars.asm
user$ ld 9stars.o -o 9stars
ld: warning: -macosx_version_min not specified, assuming 10.10
user$ ./9stars

the expected output should be:

Displaying 9 stars
*********
user$

but the current output is:

Displaying 9 stars
*********user$

It looks like write_string new_line, 1 does not treat new_line as a character constant although in db 'Displaying 9 stars', new_line the new_line adds a new line character, the character code 10. My initial guess is that new_line isn't a character constant at all. What could be the reason for this? How could this be fixed? I'm on Mac OS X 10.10. I have a core i5 m540 Intel CPU. I use NASM version 2.11.06.

Upvotes: 2

Views: 2487

Answers (1)

Paul R
Paul R

Reputation: 213190

write_string expects the address of a string, but new_line is just the character value 0xa. Trying to interpret this as the address of a string will give unpredictable results. If you want a string that just contains a single 0xa that you can print then you'd need to do something like this:

    section .data

message:    db 'Displaying 9 stars', new_line       ; a message
.length:    equ current_address - message           ; length of the message
asterisks:  times 9 db '*'                          ; a string of 9 asterisks
newline:    db new_line                             ; <<< a single LF

global start

    section .text

start:                                      ; linker entry point

    write_string message, message.length    ; print a message to standard output
    write_string asterisks, 9               ; print 9 asterisks
    write_string newline, 1                 ; <<< print LF

Upvotes: 5

Related Questions