I'm writing a program in assembly that is suppose to take the value of a key press, store it in a register and see what the value is.
I have managed to save 0x00000002 after pressing the key 2, into the register I wanted to save it in which is called "r1".
Now this is where I get lost. I'm now trying to compare this to some hexadecimals, so that I then can get know what the value is and use it in an other function. This is how my code looks like:
cmp r1, #0x30
beq savekey
cmp r1, #0x31
beq savekey
cmp r1, #0x32
beq savekey
cmp r1, #0x33
beq savekey
cmp r1, #0x34
beq savekey
cmp r1, #0x35
beq savekey
cmp r1, #0x36
beq savekey
cmp r1, #0x37
beq savekey
cmp r1, #0x38
beq savekey
cmp r1, #0x39
beq savekey
The expected result of this I thought would be that it would go in to the function "savekey" whenever it recognize that it was a number. However this never happens and it just skips all of them.
How could I do the comparison between the register and the hexadecimal different so it will work correctly? And is there any simpler way I can write this so I don't have to write a case for every single digit?
I solved it through replacing for example #0x38 with #8. However I'm still wondering how to simplify the code.
You can do a range check in assembler. In 'C' this would be something like, if(x >= '0' && x < ((int)'9')+1) savekey();
. The equivalent ARM assembler would be like,
cmp r1, 0x30
blo bad_value
cmp r1, 0x3A
bhs bad_value
b save_key
You need to have a branch to the bad case unless you use a temporary register. The you can subtract the base (0x30), treat the temporary as unsigned
and test for the higher case. Here is something like that,
sub r2, r1, 0x30 @ low values will wrap to a high unsigned value
cmp r2, 10 @ in range (0-9)?
blo save_key
; bad/error handling here.
As others have noted, your ASCII value might already need this subtraction to convert to a binary or machine value.
User contributions licensed under CC BY-SA 3.0