Похоже, ваш код немного запутан, и трудно понять, какой алгоритм вы пытаетесь реализовать.
При подходе к такой проблеме обычно помогает записать основы 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!