I was having troubles today with MIPS.
I wanted to do something clever, and re-write this complex if-statement:
if (c >= 'A' && c <= 'Z')
as
if ((unsigned) (c-'A') <= ('Z'-'A'))
Here's C that works as I expect:
#include <stdio.h>
int main(void) {
char c = ',';
if ((unsigned) c - 'A' <= 0) {
putchar('~');
}
putchar('.');
return 0;
}
How do I write that in MIPS?
My attempt doesn't work as I'd expect.
It looks like MIPS thinks that (unsigned) 44 - 65
(for example) is less than 0
.
Here's a Minimal, Complete, and Verifiable example of my problem:
.text
.globl main
main:
li $a0, ','
subu $a0, $a0, 'A'
ble $a0, $0, LESS
j END
LESS:
li $a0, '~'
li $v0, 11
syscall
j END
END:
li $a0, '.'
li $v0, 11
syscall
li $v0, 10
syscall
I expect it to output only .
, because after
li $a0, ','
subu $a0, $a0, 'A'
I expect $a0
to contain some large positive integer (I thought subu
was unsigned subtraction?).
But the ble $a0, $0, LESS
branches, proving that apparently the unsigned ',' - 'A'
(or 44 - 65
) is less than 0.
How do I get this to not branch:
li $a0, ','
subu $a0, $a0, 'A'
ble $a0, $0, LESS
and this to branch:
li $a0, 'B'
subu $a0, $a0, 'A'
ble $a0, $0, LESS