gpt4 book ai didi

linux - (x64 Nasm) Linux 上的 Writeline 函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:28:40 24 4
gpt4 key购买 nike

我正在尝试创建一个 printeline 函数,但是当我比较来自 rsp 地址的值时 cmp 失败。

这是通用打印函数所在的位置:

    print:
push rdx
push rcx
push rbx
push rax

call stringlen ;calls stringlen. new return address assigned to rbx

mov rdx, rax ;move rax (containing string length) to rdx
pop rax ; restore original rax argument value (string address)

mov rcx, rax ; move msg address to rcx
mov rbx, 1 ; stdout
mov rax, 4 ;opcode 4 print
int 80h ;linux interrupt

pop rbx ;restore original return address to rbx
pop rcx ; restore value of rcx
pop rdx ;restore value of rdx
ret

这里是 printline 函数。它首先调用 print 来打印消息。然后它将换行符插入堆栈以获取它的地址。然后用rax中保存的换行地址再次调用print打印。

   ;prints msg with a line feed
printline:
call print ;print the message

push rax
mov rax, 0Ah ;move linefeed into rax
push rax ;push rax onto the stack
mov rax,rsp ;get the address of linefeed from rsp
call print ;print the linefeed
mov rdx, 1
mov rcx, rax
mov rbx, 1
mov rax, 4
int 80h
pop rax
pop rax
ret
;gets string length
stringlen:
push rbx ;push return address to stack
mov rbx, rax ;rax holds the argument-> msg address

我认为问题出在这里:

    nextchar:  ;do the counting
cmp byte [rax], 0h ; When comparing address from rsp, zero flag is set

设置了零标志,它跳转到 finished 而不是 inc 并循环返回:

        jz  finished
inc rax
jmp nextchar

finished:
sub rax, rbx ;store the new argument rax as msg length
pop rbx ;mov return address back into rbx
ret ;go to return address

这是在我调用 printline 的 main.asm 中:

    %include "stdio.asm"
section .data
msg db "Print message 1:Hello world", 0h

section .text
global _start

_start:
mov rax, msg
call printline ;msg is printed but no linefeed

mov rax, 0
call return

我已经通过 gdb 运行它,rsp 和 rax 似乎指向正确的值 (0x0a)。不太确定为什么 cmp 在这里设置零标志。 :(

最佳答案

64位模式不使用int 80h,那是32位系统调用接口(interface)。如果幸运的话,如果指针恰好在范围内,它可能会起作用,但不推荐这样做。但是堆栈通常在该范围之外,这就是您的代码不起作用的原因。 print 中的代码应如下所示:

print:
push rdx
push rcx
push rbx
push rax

call stringlen ; calls stringlen

mov rdi, 1 ; stdout
pop rsi ; restore original rax argument value (string address)
mov rdx, rax ; move rax (containing string length) to rdx
mov rax, 1 ; sys_write
syscall

pop rbx ; restore value of rbx
pop rcx ; restore value of rcx
pop rdx ; restore value of rdx
ret

根据需要调整保存/恢复代码。您似乎对 rbx 感到困惑,为什么您一直称其为“返回地址”?

PS:不确定 printline 中的附加 sys_write 应该做什么。

关于linux - (x64 Nasm) Linux 上的 Writeline 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30711918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com