我按照一个简单的教程创建了一个NASM x86_64程序,该程序使用定义函数打印带有换行符的变量。sprintLF调用了sprint,然后打印出rax中设置适当系统调用的任何内容。返回时,sprintLF使用0Ah换行代码更新rax,然后将其推送到堆栈,并重新分配rax到0Ah的堆栈地址,然后再次调用sprint,并在stdout中写入换行代码。在整个代码下面,我已经在gdb中调试了sprint,显示所有正确的寄存器都存储有系统调用4的值,并且我不知道为什么变量字符串成功被打印,但换行符没有。
执行代码所使用的命令及输出结果如下:
在另一个程序中,我试图将参数放入堆栈后打印它们,但同样的情况发生了,所以我只能猜测系统调用不喜欢从堆栈中取值,但我是汇编新手,这让我感到困惑。
调用代码如下:
;; Hello World Program (Externam file include)
;; Compile with: nasm -f elf64 helloworld-if.asm
;; Link with ld helloworld-if.o -o helloworld-if
;; Run with ./helloworld-inc
%include 'function.asm' ; include our external file
SECTION .data
msg1 db 'Hello, brave new world!', 0h ;our first message string add null terminating byte
msg2 db 'This is how we recycle in NASM.', 0h ; our second message string add null terminating byte
SECTION .text
global _start
_start:
mov rax, msg1 ; mov the address of our first message string into RAX
call sprintLF ; call our string printing function
mov rax, msg2 ; move the address of our second message string into RAX
call sprintLF ; call our string printing function
call quit ; call our quit function
实用函数
; -------------------------------------------------------------------------------------------------------------------
; int slen(String message)
; String length calculation function
slen: ; this is our first function declaration
push rbx ; push the value in RBX onto the stack to preserve it while we use RBX in this function
mov rbx, rax ; move this address in RAX into RBX ( Both point to the same segment in memory)
nextchar:
cmp byte [rax], 0 ; this is the same as lesson 3
jz finished
inc rax
jmp nextchar
finished:
sub rax, rbx
pop rbx ; pop the value on the stack back into RBX
ret ; return to where the function was called
;; ---------------------------------------------------------------------------------------------------------
;; void sprint(String message)
;; String printing function
sprint:
push rdx
push rcx
push rbx
push rax
call slen
mov rdx, rax
pop rax
mov rcx, rax
mov rbx, 1
mov rax, 4
int 80h
pop rbx
pop rcx
pop rdx
ret
;; ----------------------------------------------------------------------------------------------------------
;; void sprintLF(String message)
;; String printing with line feed function
sprintLF:
call sprint
push rax ; push rax onto the stack to preserve it while we use the rax register in this function
mov rax, 0Ah ; push 0Ah into rax, 0Ah is the ascii character for a linefeed
push rax ; push the linefeede onto the stack so we can get the address
mov rax, rsp ; move the address of the current stack pointer into rax for sprint -> because write requires a memory address
call sprint ; call our sprint function
pop rax ; restore out linefeed character from the stack
pop rax ; return to our program
ret
;; -----------------------------------------------------------------------------------------------------------
;; void exit()
;; Exit program restore resources
quit:
mov rbx, 0
mov rax, 1
int 80h
ret
执行代码所使用的命令及输出结果如下:
nasm -f elf64 helloworld-if.asm
ld helloworld-if.o -o hellworld-if
./hellworld-if
Hello, brave new world!This is how we recycle in NASM.
在另一个程序中,我试图将参数放入堆栈后打印它们,但同样的情况发生了,所以我只能猜测系统调用不喜欢从堆栈中取值,但我是汇编新手,这让我感到困惑。
int 0x80
。 - Peter Cordes