assembly X64装配线功能

lp0sw83n  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(108)

我正在学习汇编语言,在尝试创建一个字符串转换函数时,它接收一个字符串并返回一个UPPERCASEd字符串,我被下面的代码卡住了:

asm_func3:
        mov             rbp, [rax]              ; stores argument received in rbp
        push            rcx                     ; prepare rcx for use
        xor             rcx,rcx                 ; zero counter
        
_toupper:
        cmp             byte [rbp+rcx], 61h     ; is lowercase ascii?
        jl              _toupper_next           ; no, go to next char

        cmp             byte [rbp+rcx], 7Ah     ; is lowercase ascii?
        jg              _toupper_next           ; no, go to next char
        
        sub             byte [rbp+rcx], 20h     ; subtract 32 to convert lowercase to uppercase

_toupper_next:  
        inc             rcx                     ; next char
        cmp             byte [rbp+rcx], 0h      ; is end of string?
        jne             _toupper                ; start again

_toupper_end:
        mov             rax, rbp                ; copy the result to return register
        pop             rcx                     ; release rcx
        ret

我接到一个信号车:

cmp             byte [rbp+rcx], 61h     ; is lowercase ascii?

我从一个C程序调用这个函数如下:

printf("%s", asm_func3("abcdef\n"));

我怀疑我没有正确处理RBP,但我用尽了我所有的信息来源。有人能帮帮我吗?

xu3bshqb

xu3bshqb1#

工作代码:

; Function: asm_func3
; Purpose: Convert all lowercase letters in a source string to uppercase and store the result in a destination buffer.
; Parameters:
;   rdi: Pointer to the source null-terminated string.
;   rsi: Pointer to the destination buffer.
; Returns:
;   rax: Pointer to the destination buffer containing the converted string.

asm_func3:
        ; Preserve the base pointer, as it's callee-saved.
        push  rbp                     

        ; Initialize rcx (our character offset counter) to 0.
        xor   rcx, rcx                 

_toupper:
        ; Load the next character from the source string into the al register.
        mov   al, byte [rdi]           

        ; Check if we've reached the end of the source string.
        cmp   al, 0h                   
        je    _toupper_end              ; If yes, jump to the function's end sequence.

        ; Check if the character is a lowercase letter.
        ; ASCII values: 'a' is 61h and 'z' is 7Ah.
        cmp   al, 61h                  
        jl    _toupper_next             ; If character is less than 'a', skip to the next character.
        cmp   al, 7Ah                  
        jg    _toupper_next             ; If character is greater than 'z', skip to the next character.
        
        ; Convert the lowercase character to uppercase.
        ; ASCII conversion: Uppercase letters are 32 less than their lowercase counterparts.
        sub   al, 20h                  

_toupper_next:   
        ; Store the (potentially converted) character into the destination buffer.
        mov   byte [rsi + rcx], al     

        ; Increment both the source pointer and our character offset counter.
        inc   rdi                      
        inc   rcx                      

        ; Jump back to the start of the loop to process the next character.
        jmp   _toupper                 

_toupper_end:
        ; Null-terminate the destination buffer.
        mov   byte [rsi + rcx], 0h     

        ; Set the return value to the base address of the destination buffer.
        mov   rax, rsi                 

        ; Restore the base pointer and return from the function.
        pop   rbp                      
        ret
6ljaweal

6ljaweal2#

谢谢大家的评论。在查看了文档之后,我设法让下面的代码工作。还有其他意见吗?

asm_func3:
        push            rbp                     ; must be preserved
        xor             rcx,rcx                 ; zero counter
        mov             dl, byte [rdi+rcx]      ; copy one byte

_toupper:
        cmp             dl, byte 61h            ; is lowercase ascii?
        jl              _toupper_next           ; no, go to next char 
        cmp             dl, byte 7Ah            ; is lowercase ascii?
        jg              _toupper_next           ; no, go to next char
        sub             dl, 20h                 ; subtract 32 to convert lowercase to uppercase

_toupper_next:   
        mov             byte [rsi+rcx], dl      ; save byte on rsi
        inc             rcx                     ; next char
        mov             dl, byte [rdi+rcx]      ; copy one more byte
        cmp             dl, 0h                  ; is end of string?
        jne             _toupper                ; start again
        mov             rax, rsi                ; copy rsi to rax to return
        pop             rbp                     ; restore rbp
        ret

现在我只需要弄清楚如何清除RSI,从以前的呼叫中删除任何“垃圾”。

相关问题