MIPS - 将数字转换为十六进制

时间:2014-12-03 02:04:13

标签: assembly mips

所以我正在进行汇编编程任务,我们的老师要求我们在数组中输入5个数字(它们必须大于0且小于65536),然后将它们取回,将它们转换为十六进制,然后将其打印出来。他给出了转换为十六进制的方法,如下所示:

(1)对值15和参数执行逻辑AND。

(2)如果结果小于10,则将其添加到字符' 0'的ASCII码中。否则,减去它 10,然后将其添加到字符“A'。

的ASCII码中

(3)将参数向右移动四位。

(4)重复上述过程四次。

(5)取上面得到的四个结果中的最低8位,将它们合并为一个 注册并返回。

认为我已经正确完成了步骤1-4,但我并不完全理解第5步,有人可以帮我弄清楚该做什么吗?他的意思是"四个结果的最低8位"?我已经在下面提供了我的代码(它完成了第4步的所有操作,但我还没有对第5步的部分进行编码,因为我不理解它。

# MIPS Programming Assignment 3

.data
    msg: .asciiz "\nPlease enter an integer: " #input prompt
    error: .asciiz "\nYour number is out of range, try again!"
    array: .space 20            #reserve space for 5-integer array
.text
main:
la $t3, array #load pointer for traversing array
la $s0, array #load initial position of array

#initialize counter for loop
add $t0, $t0, $zero #set counter to 0
li $t1, 5 #set maximum number of passes to 5

#initialize counter for hexadecimal loop
add $t4, $t4, $zero #set counter to 0
la $t5, array #load pointer for traversing array

#loop to insert numbers into array
insert_loop:
    beq $t0, $t1, hexadecimal_loop #if $t0 = $t1 then exit loop
    li $v0, 4 #system call code for printing string
    la $a0, msg
    syscall
    li $v0, 5 #system call for reading integer
    syscall
    move $t2, $v0 #move read integer to $t2
    bltz $t2, error_msg #bltz = branch if ($t2) < zero
    bgt  $t2, 32768, error_msg #branch if t2 > 32768
    sw $t2, ($t3) #stores t2 in t3 array
    addi $t3, $t3, 4 #increment array by 4 (move to next index)
    addi $t0, $t0, 1 #increment counter by 1
    j insert_loop

#loop for hexadecimal subprogram
hexadecimal_loop:
    add $s2, $s2, $zero  #set counter for loop
    li $s3, 5 #set max number of passes to 5
    beq $t4, $t1, exit #when $t4 = $t1, then exit loop
    lw $s1, ($t5) #store array value into $s1
    add $a0, $zero, $s1  #"move" value to $a0 to use as parameter
    jal hexadecimal
    addi $t5, $t5, 4 #increment array by 4 (move to next index)

#hexadecimal subprogram
hexadecimal:
    add $t5, $a0, $zero #copy parameter to $t5
    beq $s2, $s3, return_result #when $s2 = $s3 then exit loop
    andi $t6, $t5, 15 #logical AND on $t5 and 15
    addi $t7, $t7, 10 #variable to check again
    bgt $t6, $t7, more_than_ten #if $t6 > 10
    blt $t6, $t7, less_than_ten #if $t6 < 10
    addi $s2, $s2, 1 #increment counter by 1

#error message display
error_msg:
    li $v0, 4
    la $a0, error
    syscall
    j insert_loop
less_than_ten:
    addi $t7, $t6, 10
    srl $t5, $t5, 4
    j hexadecimal
more_than_ten:
    addi $t7, $t6, -10
    addi $t7, $t7, 65
    srl $t5, $t5, 4
    j hexadecimal
exit:
    li $v0, 10   # System call code for exiting program
    syscall

1 个答案:

答案 0 :(得分:0)

您要转换的数字小于65536,因此它将适合16位。那是4个十六进制数字。每个十六进制数字可以表示为ASCII字符,它适合单个字节(8位),因此您可以在一个32位寄存器中获得所有四位数的ASCII表示。

算法的第2步和第3步在您用于计算的寄存器的低字节中给出一个ASCII字符。这个低字节是&#34;最低的8位&#34;你老师在说什么。

您需要将此低字节存储在某个寄存器中(当您返回时调用者将查看的寄存器)。但是因为你重复了第2步和第3步,你需要确保以一种不会被进一步迭代覆盖的方式存储它。

可能性是:

  1. 在开始之前将存储寄存器设置为零。
  2. 每次完成算法的第2步
    • 将存储寄存器左移8位
    • 将您的ASCII值(一个字节)添加到寄存器
  3. 具体而言,如下:

    1. 存储寄存器Rx:0x00000000
    2. 第一次通过算法步骤2
      • Shift Rx left给出0x00000000
      • 将ASCII值(例如&#39; A&#39; = hex 29)添加到Rx给出0x00000029
    3. 第二次通过算法步骤2
      • Shift Rx left给出0x00002900
      • 添加ASCII值(比如&#39; 1&#39; = hex 1F)到Rx给出0x0000291F
    4. 第三次通过算法步骤2
      • 左移Rx给出0x00291F00
      • 将ASCII值(例如&#39; 7&#39; = hex 25)添加到Rx给出0x00291F25
    5. 第四次通过算法步骤2
      • Shift Rx left给出0x291F2500
      • 将ASCII值(例如&#39; 2&#39; = hex 20)添加到Rx给出0x291F2520
    6. 完成后,寄存器(Rx)应包含您的4个ASCII字符&#39; A&#39;,&#39; 1&#39;,&#39; 7&#39;,&#39; 2&#39; (可能是相反的顺序,取决于你想用它们做什么)。调用函数可以在Rx中查找,例如,将它们打印出来。