; \注释后的指令不执行? NASM中评论中的反斜杠有什么特别之处?

时间:2019-09-11 12:23:52

标签: assembly x86-64 nasm

我正在ASM中对ASCII到十进制转换器进行编程,并且在编辑后,它没有添加到rax中,这导致了无限循环。 GDB表示rax不接受任何数字,即使从内存和其他寄存器中移出也是如此。

我尝试使用rax将事物移至mov,并且还尝试了inc操作。

这是asciiToDec函数,它的注释很好,我将ASCII数字的位置压入堆栈,然后将其数量压入堆栈,然后调用此函数。

    asciiToDec:                     ; Converts a number in ASCII to decimal that the computer can understand
        pop rax                     ; Remove the ret pointer so that it isnt popped off later when the other values are popped
        pop qword[amount]           ; Remove the amount of characters from the stack
        pop qword[location]         ; Remove the location from the stack
        push rax                    ; Push the ret pointer back onto the stack
        mov rax,1                   ; Move 1 into rax since 0*x==0 so 1*x==10 where x=10
        mov rbx,10                  ; Move 10 into rbx
        mov rcx,[amount]            ; Move the amount of stuff into rcx
        sub rcx,1                   ; Subtract one since the one's digit needs to be multiplied by 1 not 10
;-----------------------------------;
        loop1:                      ; Stage 1: Counts the power of 10 that is needed for the first number, highest digit
            mul rbx                 ; Multiply rax by rbx, rax*10
            sub rcx,1               ; Subtract 1 from rcx
            cmp rcx,0               ; Test if rcx==0
            jne loop1               ; Repeat if rcx>0
            mov [power10],rax       ; Move the power of ten into the power10 variable
            xor rax,rax             ; Set rax to 0 via xoring the bits to 0
            mov rbx,[location]      ; Move the location of the ASCII into rbx
;-----------------------------------;
        loop2:                      ; Stage 2: Actually converts the ASCII to decimal by subtracting ASCII '0'
            xor rcx,rcx             ; Remove previous data
            mov cl,byte[rbx+rax]    ; Copy new data into the low byte of rcx
            cmp cl,10               ; Next 4 lines: test for newlines and carrige returns, shouldn't have any but just making sure
            je  loop2               ; /\
            cmp cl,13               ; /\
            je  loop2               ; /\
            add rax,1               ; INC rax so we have the next byte
            sub cl,'0'              ; Make it decimal and not ASCII
            cmp cl,9                ; Test if the value in cl is equal to 9
            jg  failFun             ; If greater than 9 then the ASCII value in this index was not 0-9
            push rax                ; Get the data in rax out of the way so we can do some calculations with rax
            mov al,cl               ; Move the byte in cl to al, 0-9
            mul qword[power10]      ; Multiply rax (al is the lowest 8 bits of rax) by the power of 10
            mov rcx,rax             ; Move the val in rax back to rcx for later use
            mov rax,[power10]       ; Move the power of 10 to rax
            push rbx                ; Get the data in rbx out of the way, like rax
            mov rbx,10              ; Move 10 into rbx
            div rbx                 ; Divide rax (power of ten) by rbx (10) to get the next lower digit's power
            pop rbx                 ; Get back the data that was in rbx
            mov [power10],rax       ; Move the power of 10 back into the `power10` variable from rax
            pop rax                 ; Get rax's data back
            add [total],rcx         ; Add rcx to the total
            cmp rax,[amount]        ; Compare rax to the amount of characters
            jne loop2               ; If we haven't gone through all the characters, loop again
        pop rax                     ; Get the ret pointer out of the stack so I can have it on the top later
        push qword[total]           ; Move the total into the stack
        push rax                    ; and push the ret pointer back on top
        jmp clean                   ; Jump to clean
;-----------------------------------;
        failFun:                    ; Stage 3: An option for the function to go through if stage 2 fails
            push qword fail
            push qword failLen
            call print
            pop rax
            push qword 0
            push rax
            jmp clean

我希望它可以将dec数压入堆栈,以便稍后弹出,但是rax永远不会高于0,即使在执行加法运算和mov rax,[power10]之后也会导致无限循环,因为rax从未到达[amount] 编辑:GDB输出:

Starting program: /path/to/executable/a.out 
1234

Breakpoint 1, loop2 () at common.asm:114
114             xor rcx,rcx             ; Remove previous data
(gdb) info reg rax
rax            0x0  0
(gdb) nexti
115             mov cl,byte[rbx+rax]    ; Copy new data into the low byte of rcx
(gdb) 
116             cmp cl,10               ; Next 4 lines: test for newlines and carrige returns, shouldn't have any but just making sure
(gdb) 
120             add rax,1               ; INC rax so we have the next byte
(gdb) 
121             sub cl,'0'              ; Make it decimal and not ASCII
(gdb) info reg rax
rax            0x0  0

2 个答案:

答案 0 :(得分:2)

  

您的/\注释使NASM感到困惑,并且忽略了这些行。请删除这些注释。 *实际上,反斜杠是连续的行,因此nasm认为以下几行是您的评论的其余部分-Jester

使用\删除注释可解决此问题,因为NASM认为下一行是注释。 VIM NASM语法突出显示不遵循此规则。

根据NASM手册,3.1 Layout of a NASM Source Line

  

NASM使用反斜杠(\)作为换行符; 如果一行以反斜杠结尾,则下一行被视为反斜杠结尾的行的一部分。

答案 1 :(得分:1)

仅需注意,您可以使用xor eax, eax代替xor rax, rax。前者也将64位高半部分清零,但编码时间短了1个字节。 mov eax, 1mov rax, 1的情况相同。

通常,32位操作数会生成32位结果,并将其零扩展到目标通用寄存器中的64位结果(否则32位操作将依赖于64位高半部分寄存器)。有关更多详细信息,请参见x86-64 Tour of Intel Manuals