首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在程序集中将十进制转换为二进制

在程序集中将十进制转换为二进制
EN

Code Review用户
提问于 2020-12-27 11:28:10
回答 1查看 462关注 0票数 1

我的PicoBlaze模拟器在中的应用中最长的示例程序是这个十进制到二进制转换器:

代码语言:javascript
复制
;This is an example program that uses
;UART, the interface that PicoBlaze uses
;for connecting to terminals (a DOS-like
;user interface, with a keyboard and a
;screen capable of displaying text).
;It loads base-10 integer numbers from
;the terminal, converts them into binary,
;and then prints the binary
;representations back onto the terminal.
;Example input would be: 

;1
;2
;4
;8
;15
;127
;255
;

;And the expected output is: 

;1_(10)=1_(2)
;2_(10)=10_(2)
;4_(10)=100_(2)
;8_(10)=1000_(2)
;15_(10)=1111_(2)
;127_(10)=1111111_(2)
;255_(10)=11111111_(2)
;

;Note that you need to click the
;"Enable UART" button in order to use it.
;Also, the trailing empty line in the
;input is necessary for the result to be
;printed.

;Now follows some boilerplate code
;we use in our Computer Architecture
;classes...
CONSTANT LED_PORT,00
CONSTANT HEX1_PORT,01
CONSTANT HEX2_PORT,02
CONSTANT UART_TX_PORT,03
CONSTANT UART_RESET_PORT,04
CONSTANT SW_PORT,00
CONSTANT BTN_PORT,01
CONSTANT UART_STATUS_PORT,02
CONSTANT UART_RX_PORT,03
; Tx data_present
CONSTANT U_TX_D, 00000001'b
; Tx FIFO half_full
CONSTANT U_TX_H, 00000010'b
; TxFIFO full
CONSTANT U_TX_F, 00000100'b
; Rxdata_present
CONSTANT U_RX_D, 00001000'b
; RxFIFO half_full
CONSTANT U_RX_H, 00010000'b
; RxFIFO full
CONSTANT U_RX_F, 00100000'b

ADDRESS 000
START:
;At the beginning, the number is 0.
load s0,0
;And we are storing its string
;representation at the beginning
;of RAM.
namereg s3,pointer
load pointer,0
;Now follows a loop to load
;the digits of the number.
loading_the_number:
  ;Load a character from the UART
  ;terminal.
  call UART_RX
  ;Check whether the character is a digit.
    compare s9,"0"
    ;If it is not a digit, jump to the
    ;part of the program for printing
    ;the number you have got.
    jump c,print_the_number
    load s1,"9"
    compare s1,s9
    jump c,print_the_number
  ;If it is a digit, store it into RAM.
  store s9,(pointer)
  add pointer,1
  ;Multiply the number you have got by 10.
  load sf,s0
  call multiply_by_10
  load s0,se
  ;Then, convert the digit from ASCII
  ;into binary.
  sub s9,"0"
  ;And then add it to the number you
  ;have got.
  add s0,s9
  call c,abort ;In case of overflow.
  jump loading_the_number ;Repeat until a
                          ;non-digit is
                          ;loaded.
print_the_number:
;If there are no digits to be printed,
;do not print anything.
sub pointer,0
jump z,START
print_the_decimal:
load s4,pointer
load pointer,0
printing_the_decimal_loop:
  compare pointer,s4
  jump nc, end_of_printing_the_decimal
  fetch s9,(pointer)
  ;Do some basic sanity check: Is the
  ;character you are printing indeed
  ;a decimal digit?
    compare s9,"0"
    call c,abort
    load s1,"9"
    compare s1,s9
    call c,abort
  ;If it is indeed a decimal digit,
  ;print it.
  call UART_TX
  add pointer,1
  jump printing_the_decimal_loop
end_of_printing_the_decimal:
;After you have repeated the decimal
;number, print the string "_(10)=".
load s9,"_"
call UART_TX
load s9,"("
call UART_TX
load s9,"1"
call UART_TX
load s9,"0"
call UART_TX
load s9,")"
call UART_TX
load s9,"="
call UART_TX
;If the number to be printed is
;equal to zero, print 0.
sub s0,0
jump nz,print_the_binary
load s9,"0"
call UART_TX
jump end_of_printing_loop
print_the_binary:
;Make the pointer point to the
;beginning of RAM.
load pointer,0
;Now goes a loop which stores the binary
;representation of the number we have
;got into RAM, but reversed.
beginning_of_converting_to_binary:
  sub s0,0
  jump z,end_of_converting_to_binary
  load s9,"0"
  sr0 s0
  jump nc,store_digit_to_memory
  add s9,1
  store_digit_to_memory:
  store s9,(pointer)
  add pointer,1
  jump beginning_of_converting_to_binary
end_of_converting_to_binary:
;Do some basic sanity check, such as that
;the pointer does not point to zero.
compare pointer,0
call z,abort ;Something went wrong
             ;so end the program.
;Check whether there are more than 8 bits.
compare pointer,9
call nc,abort
;Now goes a loop which will print
;the binary number in RAM, with digits
;in the correct order. The pointer now
;points at a memory location right after
;the binary number (not at the last digit,
;but after it).
beginning_of_printing_loop:
  sub pointer,1
  jump c,end_of_printing_loop
  fetch s9,(pointer)
  ;Do some basic sanity check:
  ;Is the character the pointer points to
  ;indeed a binary digit?
    compare s9,"0"
    jump z,memory_is_fine
    compare s9,"1"
    jump z,memory_is_fine
    call abort ;Something went wrong,
               ;so end the program.
  memory_is_fine:
  ;If everything is fine, print that
  ;digit.
  call UART_TX
  ;Repeat until you have printed all
  ;digits of the binary number
  ;stored in RAM.
  jump beginning_of_printing_loop
end_of_printing_loop:
;After you have printed that binary
;number, print the string "_(2)" and
;a new-line.
load s9,"_"
call UART_TX
load s9,"("
call UART_TX
load s9,"2"
call UART_TX
load s9,")"
call UART_TX
load s9,a ;newline character, 0xa=='\n'.
call UART_TX
;The program runs in an infinite loop...
JUMP START

multiply_by_10:
  load se,sf
  add se,se
  call c,abort
  add se,se
  call c,abort
  add se,sf
  call c,abort
  add se,se
  call c,abort
return

abort:
  load s9,"E"
  call UART_TX
  load s9,"R"
  call UART_TX
  load s9,"R"
  call UART_TX
  load s9,"O"
  call UART_TX
  load s9,"R"
  call UART_TX
  load s9,"!"
  call UART_TX
  load s9,a ;newline
  call UART_TX
  infinite_loop:
  jump infinite_loop
return

;Now follows some boilerplate code
;we use in our Computer Architecture
;classes...
UART_RX:
  INPUT sA, UART_STATUS_PORT
  TEST sA, U_RX_D
  JUMP Z, UART_RX
  INPUT s9, UART_RX_PORT
RETURN

UART_TX:
  INPUT sA, UART_STATUS_PORT
  TEST sA, U_TX_F
  JUMP NZ, UART_TX
  OUTPUT s9, UART_TX_PORT
RETURN

那你觉得呢?你对如何使它变得更好有一些建议吗?

EN

回答 1

Code Review用户

回答已采纳

发布于 2020-12-27 23:50:53

可读性差

您应该插入更多的空行,以便干净地分离逻辑代码块。

你对缩进的使用并不完全一致。如果你做得对,它将大大提高可读性。

而且,考虑到您可以使用一些别名(namereg s3,pointer),我认为您可以更经常地使用它来提高可读性。

我觉得你的“基本精神健康检查”更像是“精神错乱”检查。你不应该那么怀疑。额外的代码也增加了出错的风险。

当出现问题时,您将进入程序的中止部分,不再返回。看到大多数时候您使用call来完成这个任务,而不是使用更加清晰的jump,这是令人困惑的。

优化

如果使用ASCII字符集,则冒号字符(":")紧跟字符"9“。您可以简化有效数字的验证(不再需要临时寄存器s1),例如:

代码语言:javascript
复制
compare s9,"0"
jump c,print_the_number
compare s9,":"
jump nc,print_the_number

尽量减少指令的数量,当然也控制传输指令,是很重要的。我已经把越有可能跳回不太可能的跳跃移回流产。

代码语言:javascript
复制
jump nc,loading_the_number ;Repeat until a non-digit is loaded.
jump abort

;如果要打印的数字是;等于零,则打印0。子s0,0跳nz,print_the_binary load s9,"0“调用UART_TX跳转end_of_printing_loop

如果号码是零的话,你不需要特殊情况。它将刮去无数的指令。

你的大部分循环都是有条件的,无条件的跳转,返回到顶部。使用重复-直到循环将更快,并要求只有一个条件跳转指令。

新的守则:

代码语言:javascript
复制
START:
  load s0,0
  namereg s3,pointer
  load pointer,0

loading_the_number:
  call UART_RX
  compare s9,"0"
  jump c,print_the_number
  compare s9,":"
  jump nc,print_the_number
  store s9,(pointer)
  add pointer,1
  load sf,s0
  call multiply_by_10
  load s0,se
  sub s9,"0"
  add s0,s9
  jump nc,loading_the_number ;Repeat until a non-digit is loaded.
  jump abort

print_the_number:
  sub pointer,0 ;If there are no digits to be printed, do not print anything.
  jump z,START

  load s4,pointer
  load pointer,0
printing_the_decimal_loop:
  fetch s9,(pointer)
  call UART_TX
  add pointer,1
  compare pointer,s4
  jump c,printing_the_decimal_loop

  ... some fixed text gets outputted here


  load pointer,0                    ; Works even if s0 == 0
beginning_of_converting_to_binary:  ; This stores in reverse order!
  load s9,"0"
  sr0 s0
  jump nc,store_digit_to_memory
  load s9,"1"
store_digit_to_memory:
  store s9,(pointer)
  add pointer,1
  sub s0,0
  jump nz,beginning_of_converting_to_binary

  ; pointer is certainly not zero
  sub pointer,1
beginning_of_printing_loop:
  fetch s9,(pointer)
  call UART_TX
  sub pointer,1
  jump nc,beginning_of_printing_loop

  ... some fixed text gets outputted here

  JUMP START
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/253951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档