简体   繁体   English

(x64 Nasm)Linux上的Writeline函数

[英](x64 Nasm) Writeline function on Linux

I'm trying to make a printeline fuction, but the cmp fails when I am comparing the value from rsp address. 我正在尝试进行printeline功能,但是当我比较rsp地址中的值时,cmp失败。

This is where the generic print function is: 这是通用打印功能所在的位置:

    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

Here is the printline fuction. 这是打印线功能。 It calls print to print the message first. 它调用print首先打印消息。 It then pushes linefeed onto the stack to get the address of it. 然后,它将换行符压入堆栈以获取其地址。 Then it calls print again with the linefeed address stored in rax to print it. 然后,它将再次调用print,并将换行地址存储在rax中以进行打印。

   ;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

I think the issue is here: 我认为问题出在这里:

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

The zero flag is set and it jumps to finished instead of inc and looping back: 设置了零标志,它跳到完成而不是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

This is in main.asm where I am calling 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

I have ran it through gdb and the rsp and rax seems to be pointing to the correct value (0x0a). 我已经通过gdb运行它,而rsp和rax似乎指向正确的值(0x0a)。 Not really sure why cmp set the zero flag here. 不太确定为什么cmp在这里设置零标志。 :( :(

64 bit mode does not use int 80h , that's the 32 bit system call interface. 64位模式不使用int 80h ,这是32位系统调用接口。 If you are lucky, it might work if the pointers happen to be within range but it's not recommended. 如果幸运的话,如果指针恰好在范围内,则可能会起作用,但不建议这样做。 However the stack is usually outside of that range, which is why your code doesn't work. 但是堆栈通常不在该范围内,这就是为什么您的代码不起作用的原因。 The code in print should look like: 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

Adjust the save/restore code as necessary. 根据需要调整保存/恢复代码。 You seem to be confused about rbx , why do you keep calling it "return address"? 您似乎对rbx感到困惑,为什么一直将其称为“回信地址”?

PS: Not sure what the additional sys_write inside the printline is supposed to do. PS:不知道什么额外的sys_write内部printline应该做的事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM