2014-12-17 2 views
1

В приведенном ниже коде NASM запускает все, как ожидалось, за исключением печати нового символа линии в конце. Что может быть причиной?Почему следующий код сборки не распечатывает символ новой строки (0xa)?

%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 

после сборки:

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

ожидаемый результат должен быть:

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

но выходной ток:

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

Похоже, write_string new_line, 1 не лечит new_line как константа cahracter , хотя в db 'Displaying 9 stars', new_linenew_line добавляет новый символ линии, код charcter 10. Моя основная догадка заключается в том, что new_line не является константой chacter вообще. Что может быть причиной этого? Как это можно исправить? Я нахожусь в Mac OS X 10.10. У меня есть процессор Intel i5 m540. Я использую NASM версии 2.11.06.

+0

ли не макинтош использовать 'CR' (код' 13')? – Jester

+0

@Jester: это было в «классической» Mac OS, вплоть до 2000 года. Mac OS X по существу * nix, хотя и использует LF (0xa), как и предполагалось природой. –

+0

Если вы используете '0xd' для new_line, вы получите вывод' ********* user $ 'и 'Отображение 9 звезд' не будет печататься. Это потому, что CR возвращает курсор в первую позицию (слева), тем самым удаляя «Отображение 9 звезд», в отличие от LF, который подает одну строку, перемещая курсор на одну строку вниз. – ilgaar

ответ

4

write_string ожидает адрес строки, но new_line только значение характера0xa. Попытка интерпретировать это как адрес строки даст непредсказуемые результаты. Если вы хотите строку, которая содержит только один 0xa, что вы можете печатать, то вам нужно сделать что-то вроде этого:

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 
+2

Actaully, его довольно предсказуемый - 0xa не будет действительным адресом, поэтому системный вызов завершится с EFAULT и ничего не напечатает. Поскольку он не проверяет наличие ошибок в системном вызове, он ничего не делает. –

+0

Это правда, поэтому я должен передавать адрес строки, а не значение символа. (+1) Я осознаю свою ошибку сейчас. но если я использую 'newline: db new_line; <<< a single LF' Это победит мою первоначальную цель, которая должна была определить значимую константную строку, которая могла бы использоваться через код. Чтобы устранить необходимость в 'newline: db new_line', который выглядит излишним, могу ли я сделать' new_line: db 0xa' и использовать его вместо этого? то как я могу использовать его для создания «сообщения»? так как 'message: db 'Отображение 9 звезд', new_line' не будет работать после' new_line: db 0xa' – ilgaar

+1

Обычно вы просто используете 'new_line' как часть любой строки, которую вы определяете (как и для' message') , Для единственной new_line сама по себе, хотя нет ничего плохого в использовании строки 'newline', как указано выше, вам нужно только определить это разумеется, и вы сможете использовать ее повсюду. Альтернативно рассмотрим реализацию макроса 'write_char', который выводит только одно знаковое значение, тогда вы можете просто написать' write_char new_line'. –

Смежные вопросы