Преобразовать строку в верхний регистр - PullRequest
1 голос
/ 01 марта 2020

Я пытаюсь перебрать строку в ассемблере, изменить строчные буквы на прописные, и остановиться, когда строка равна 0, но что-то кажется очень неправильным (мне кажется, что отсутствует концепция). Я не могу понять, в чем проблема или что происходит.

Вот что у меня есть:

Upper:
        movq    (%rbx), %rcx
        movq    $0, %rdi
        call    check
        call    fin
        add     %rdi, %rax
        ret

    fin:
        cmpb    $0x0, %r9b
        jne     check
        ret

    check:
        movb    (%rcx, %rdi), %r9b
        cmp     $'Z', %r9b
        jg      toUpper
        jmp     next

    toUpper:
        sub     %r9b, 0x20
        jmp     next

    next:
        incq    %rdi
        jmp     fin

1 Ответ

2 голосов
/ 01 марта 2020

Похоже, ваш код немного запутан, и трудно понять, какой алгоритм вы пытаетесь реализовать.

При подходе к такой проблеме обычно помогает записать основы c алгоритм в C или сначала в псевдокоде:

  • Для каждого символа c
    • Если c является нулевым байтом: Выполнено
    • Если c ниже 'a': игнорировать
    • Если c выше 'z': игнорировать
    • Остальное: добавить разницу от 'A' и 'a' до c

Это переводит почти непосредственно в следующую программу сборки:

upper:

    ; Read next character
    mov (%rdi), %al

    ; Test for zero byte
    test %al, %al
    je done

    ; Test for <'a' and >'z'
    cmp $'a', %al
    jl next
    cmp $'z', %al
    jg next

    ; We have a lower case character, so convert to upper case
    sub $0x20, %al ; Difference between 'A' and 'a'
    mov %al, (%rdi)

next:

    ; Increment pointer
    inc %rdi
    jmp upper

done:
    ret

Эта функция ожидает указатель строки в rdi и, следовательно, может вызываться напрямую из C:

#include <stdio.h>

extern void upper(char *str);

int main()
{
    char str[] = "abc 123 <=>? 987 xyz!";
    upper(str);
    printf("Upper case: %s\n", str);

    return 0;
}

выходы

Upper case: ABC 123 <=>? 987 XYZ!
...