How to convert lowercase string to uppercase in Assembly?

Asked

Viewed 892 times

1

I made this code that reads a sentence and determines whether the first letter is uppercase or not, now I have to sweep the entire sentence by changing where it’s lowercase to uppercase, but I’m having a problem with how to do this.

segment .data
msn db "Entre com uma frase:",sl
tam equ $-msn

msn1 db "Sua frase  comeca com  letra maiuscula:", sl
tam1 equ $-msn1

msn2 db "Sua frase nao comeca com  letra maiuscula:",sl
tam2 equ $-msn2

msn3 db " ",sl
tam3 equ $-msn3

sl equ 10
segment .bss
buf resb 100
buf2 resb 2


segment .text
global main
main:

     ;exibe string
      mov edx,tam    ;tamanho
      mov ecx,msn   ;ponteiro
      call print_str

 
     ;ler strim
      mov edx,100     ;tamanho da string
      mov ecx,buf    ;destino
      mov ebx, 0     ;Teclado
      mov eax, 3     ;read 
      int 0x80
      
      mov al,[buf +0]
      mov [buf2],al
      
      cmp byte[buf2,0],65
      jl minusculo 
      cmp byte[buf2,0],90
      jg minusculo 
      
      mov edx,tam1
      mov ecx, msn1  
      call print_str
 
      jmp fim
    
      
minusculo:
    
      mov edx,tam2
      mov ecx, msn2    
      call print_str

fim:      
      mov edx,tam3
      mov ecx,msn3
      call print_str

       
; ----------------- AREA DOS PROCEDIMENTOS ------------------

print_str:
    mov ebx, 1          ; Descritor (monitor = 1)
    mov eax, 4          ; Servico (print)
    int 0x80            ; Executa (exibe)
    ret             ; Devolve ao chamador

2 answers

2

The difference between upper and lower case in the ASCII table (for unstressed letters) is only the 6th bit.

To turn from lowercase to uppercase, simply reset bit 6 or make a logical AND with DFH = 1101 1111 or subtract 20H.

61H = 0110 0001 -> a

41H = 0100 0001 -> A

...

7AH = 0111 1010 -> z

5AH = 0101 1010 -> Z

To turn from uppercase to lowercase, simply set bit 6 or make a logical OR with 20H = 0010 0000 or add 20H.

41H = 0100 0001 - A

61H = 0110 0001 - a

...

5AH = 0101 1010 -> Z

7AH = 0111 1010 -> z

This is valid only in the 41H to 5AH and 61H to 7AH intervals.

Also note that if you use AND in the uppercase letter, it will remain uppercase, the same occurs with OR: the lowercase letter will remain lowercase.

For the program in question, read each bit of the string, compare with the range, perform a logical AND with Dfh and print or save the character.

1

I saw that the question is relatively old but I published the answer now so that it serves other Devs. To change all text to Uppercase this code works well.

.date

texto: .space 256

.text

main:

li $v0, 8
li $a1, 256
la $a0, texto
syscall

li $v0, 4
li $t0, 0

loop:

lb $t1, texto($t0)
beq $t1, 0, exit
blt $t1, 'a', not_lower
bgt $t1, 'z', not_lower
sub $t1, $t1, 32
sb $t1, texto($t0)
not_lower:
    addi $t0, $t0, 1
j loop

Exit:

li $v0, 4
la $a0, texto
syscall

li $v0, 10
syscall

Browser other questions tagged

You are not signed in. Login or sign up in order to post.