Reputation: 7
I'm trying to iterate over a string in assembly, and change the lower case letters to upper case, and stop when the string is 0, but something seems very wrong (I seem to be missing a concept). I can't figure out what the problem is or what is going on.
Here is what I have so far:
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
Upvotes: 1
Views: 490
Reputation: 9606
As it looks, your code is a bit convoluted, and it is hard to follow which algorithm you are trying to implement.
When approaching such a problem, it usually helps to write down the basic algorithm in C or pseudocode first:
c
c
is a null byte: Donec
is below 'a'
: Ignorec
is above 'z'
: Ignore'A'
and 'a'
to c
This translates almost directly to the following assembly program:
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
This function expects the string pointer in rdi
and thus can be directly called from 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;
}
outputs
Upper case: ABC 123 <=>? 987 XYZ!
Upvotes: 2