我正在学习NASM汇编程序,而且我现在因处理换行而陷入困境。
如何打印换行符?我会给你看。但是,在我展示它之前,告诉你我的平台非常重要:
$ uname -a
Linux 4.4.0-97-generic #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID : Ubuntu
Description : Ubuntu 16.04.3 LTS
Release : 16.04
Codename : xenial
我为学习准备的功能:
sprint:
push rdx
push rbx
push rax
push rcx
mov rax, rcx
pop rcx
jmp next_char
ret
sprint_syscall:
mov rbx, 1
mov rax, 4
int 80h
pop rax
pop rbx
pop rdx
ret
sprint_linefeed:
call sprint
push rcx
mov rcx, 0Ah
push rcx
mov rcx, rsp
call sprint
pop rcx
pop rcx
ret
next_char:
cmp byte [rax], 0
jz count_length
inc rax
jmp next_char
count_length:
sub rax, rcx
mov rdx, rax
jmp sprint_syscall
quit:
push rbx
push rax
mov rbx, 0
mov rax, 1
int 80h
pop rax
pop rbx
ret
主应用程序,可以使用给定功能之一:
%include 'functions.asm'
SECTION .data
msgFirst db "Hello World!", 0h
msgSecond db "Another string.", 0h
SECTION .text
global _start
_start:
mov rcx, msgFirst
call sprint_linefeed
mov rcx, msgSecond
call sprint_linefeed
call quit
一切正在编译,也很好用。如果要编译/链接:
nasm -g -f elf64 -l main.lst main.asm -o main.o && ld main.o -o main
然后执行已编译的应用程序,我们可以看到:
Hello World!Another string
正如您所看到的那样,没有任何换行,尽管调用了sprint_linefeed
函数,该函数使用下一条打印换行符的说明:
sprint_linefeed:
call sprint
push rcx ; push rcx onto the stack to preserve it
mov rcx, 0Ah ; move 0Ah into rcx, 0Ah is the ASCII char for a linefeed
push rcx ; push the linefeed char onto the stack
mov rcx, rsp ; move the address of the pointer into rcx for the 'sys_write' syscall
call sprint
pop rcx ; remove the linefeed char from the stack
pop rcx ; restore the original value of rcx
ret
因此,对我的操作的解释是指sprint()
调用给定的字符串然后将0Ah
char推送到堆栈。之后,我从RSP寄存器获取指针再次调用sprint()
函数。
已完成,因为SYS_WRITE
系统调用需要指针来打印给定字符串(http://fresh.flatassembler.net/lscr/data/004.html)。
如果要将OAh
字符添加到字符串声明:
SECTION .data
msgFirst db "Hello World!", 0Ah, 0h
调用相同的函数,但使用不同的字符串值,给我们等待结果,但它没有意义,因为sprint_linefeed()
被定义为传递冗余ASCII-char的声明。
我应该在源代码中修复哪些内容才能使sprint_linefeed()
正常工作?
答案 0 :(得分:1)
@Neverlands我通过删除sprint_linefeed
对您的functions.asm进行了一些小修改,并将以下内容放在文件的顶部:
%define newline 0Ah
SECTION .data
lineEnding db newline, 0h
sprint_linefeed:
call sprint
mov rcx, lineEnding
call sprint
ret
它可能不是你想要的,但它确实给出了:
Hello World!
Another string.
作为输出。玩得开心!