如何在NASM中正确比较命令行参数的数量?

时间:2017-03-18 02:51:29

标签: linux nasm x86-64

我正在使用Docker for Mac在Ubuntu 16.10上学习x86_64 NASM程序集。

以下程序采用两个命令行参数,并将它们相加 如果命令行参数的数量不是两个,则打印错误消息(跳转到argcError)。

当我执行此程序时,尽管传递给两个命令行参数,它仍会跳转到argcError部分。

为什么这个程序会跳转到argError

section .data
    SYS_WRITE equ 1
    STD_IN equ 1
    SYS_EXIT equ 60
    EXIT_CODE equ 0

    NEW_LINE db 0xa
    WRONG_ARGC db "Must be two command line arguments", 0xa

section .text
    global _start

_start:
    pop rcx
    cmp rcx, 3
    jne argcError
    add rsp, 8
    pop rsi
    call str_to_int

    mov r10, rax
    pop rsi
    call str_to_int
    mov r11, rax
    add r10, r11




argcError:
    mov rax, 1
    mov rdi, 1
    mov rsi, WRONG_ARGC
    mov rdx, 35
    syscall
    jmp exit


str_to_int:
    xor rax, rax
    mov rcx, 10
next:
    cmp [rsi], byte 0
    je return_str
    mov bl, [rsi]
    sub bl, 48
    mul rcx ; rax = rax * rcx
    add rax, rbx
    inc rsi
    jmp next

return_str:
    ret

int_to_str:
    mov rdx, 0
    mov rbx, 10
    div rbx
    add rdx, 48
    add rdx, 0x0
    push rdx
    inc r12
    cmp rax, 0x0
    jne int_to_str
    jmp print


print:
    ; calculate byte length of number string
    mov rax, 1
    mul r12
    mov r12, 8
    mul r12
    mov rdx, rax
    ; print sum
    mov rax, SYS_WRITE
    mov rdi, STD_IN
    mov rsi, rsp
    syscall

    jmp printNewline

printNewline:
    mov rax, SYS_WRITE
    mov rdi, STD_IN
    mov rsi, NEW_LINE
    mov rdx, 1
    syscall
    jmp exit

exit:
    mov rax, SYS_EXIT
    mov rdi, EXIT_CODE
    syscall

1 个答案:

答案 0 :(得分:0)

Micheal Petch指出,您的代码中可能存在其他错误,但您初始化RSI的方式不正确。是的,ESP确实指出了传递的参数数量,但是将其从堆栈中弹出然后再次向ESP添加8也是功能相同的。

mov     rcx, [rsp]

然后通过弹出RSI它只会成为RCX的副本。如果你想这样做,它应该是这样的

pop     rcx
.......
add     rsp, 24               ; Now RSP is pointing to proper place in array of pointers
pop     rsi
add     rsp, 16               ; Now point to pointer to second argument
pop     rsi

另一个替代方案是下一个例子,因为我个人的偏好是不使用堆栈指针而不是它的意图。

mov     rsi, rsp
lodsq                          ; Read # of arguments passed by OS
add     rsi, 8                 ; bounce over application name
cmp      al, 3
jnz     argError
push    rsi
lodsq
mov     rsi, rax               ; RSI points to first agument
call    Convert
pop     rsi
lodsq
mov     rsi, rax
call    Convert