我的问题是从用户那里得到64位密钥。为此,我需要获得16个字符作为包含十六进制字符的字符串(123456789ABCDEF)。我从用户那里获得了字符串,并使用下面的代码到达了字符。但我不知道如何将字符转换为二进制4位。在
.data
insert_into:
.word 8
Ask_Input:
.asciiz "Please Enter a Key which size is 16, and use hex characters : "
key_array:
.space 64
.text
.globl main
main:
la $a0, Ask_Input
li $v0, 4
syscall
la $a0, insert_into
la $a1, 64
li $v0, 8
syscall
la $t0, insert_into
li $t2, 0
li $t3, 0
loop_convert:
lb $t1, ($t0)
addi $t0, $t0, 1
beq $t1, 10, end_convert
# Now charcter is in $t1 but
#I dont know how to convert it to 4 bit binary and storing it
b loop_convert
end_convert:
li $v0, 10 # exit
syscall
答案 0 :(得分:0)
我不认为使用0x15掩盖,因为@ Joelmob的意见是正确的解决方案,因为
'A' = 0x41 → 0x41 & 0x15 = 0
'B' = 0x42 → 0x42 & 0x15 = 0
'C' = 0x43 → 0x43 & 0x15 = 1
'D' = 0x44 → 0x44 & 0x15 = 4
'E' = 0x45 → 0x45 & 0x15 = 5
'F' = 0x46 → 0x46 & 0x15 = 4
,它不会产生任何相关的二进制值
最简单的方法是从字符值中减去范围的下限。我将在C中提出这个想法,您可以轻松地将其转换为MIPS asm
if ('0' <= ch && ch <= '9')
{
return ch - '0';
}
else if ('A' <= ch && ch <= 'F')
{
return ch - 'A' + 10;
}
else if ('a' <= ch && ch <= 'f')
{
return ch - 'a' + 10;
}
另一种实施方式:
if ('0' <= ch && ch <= '9')
{
return ch & 0x0f;
}
else if (('A' <= ch && ch <= 'F') || ('a' <= ch && ch <= 'f'))
{
return (ch & 0x0f) + 9;
}
然而,使用下列问题中描述的技术可以进一步优化单一比较
现在可以按以下方式重写支票
if ((unsigned char)(ch - '0') <= ('9'-'0'))
if ((unsigned char)(ch - 'A') <= ('F'-'A'))
if ((unsigned char)(ch - 'a') <= ('f'-'a'))
任何现代编译器都可以进行此类优化here is an example output
hex2(unsigned char):
andi $4,$4,0x00ff # ch, ch
addiu $2,$4,-48 # tmp203, ch,
sltu $2,$2,10 # tmp204, tmp203,
bne $2,$0,$L13
nop
andi $2,$4,0xdf # tmp206, ch,
addiu $2,$2,-65 # tmp210, tmp206,
sltu $2,$2,6 # tmp211, tmp210,
beq $2,$0,$L12 #, tmp211,,
andi $4,$4,0xf # tmp212, ch,
j $31
addiu $2,$4,9 # D.2099, tmp212,
$L12:
j $31
li $2,255 # 0xff # D.2099,
$L13:
j $31
andi $2,$4,0xf # D.2099, ch,
答案 1 :(得分:-1)
看一下这个ASCII table,你会看到9和9以下数字的十六进制代码是0x9,而对于大写字母,这是在0x41和0x5A之间AZ确定它是一个数字还是字符,你看看是否如果它是一个带有0x15的字符掩码来获得四位,那么它就完成了一个数字。
如果要包含小写字母,请执行与屏蔽相同的操作,并确定其是否为0x61和0x7A之间的字符