(x64 Nasm)Linux上的Writeline功能

时间:2015-06-08 14:30:16

标签: linux assembly 64-bit nasm

我试图制作一个原色函数,但是当我比较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

设置零标志,它跳转到已完成而不是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

这是在main.asm中我打电话给printline:

    %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在这里设置零标志。 :(

1 个答案:

答案 0 :(得分:0)

64位模式不使用int 80h,这是32位系统调用接口。如果你很幸运,如果指针恰好在范围内,它可能会起作用,但不建议这样做。但是,堆栈通常在该范围之外,这就是您的代码无法正常工作的原因。 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感到困惑,为什么一直在调用它?#34;返回地址"?

PS:不确定sys_write内的其他printline应该做什么。