[英]Little Man Computer Program to output 1 with delay of 5 seconds
假設一個小人電腦程序需要 1 微秒來執行一條指令。 我需要編寫一個 LMC 程序,該程序接受 0 到 10(含)之間的輸入,並產生一個 1 的輸出,但經過那么多秒的延遲。
例如,輸入 5 將在五秒后產生輸出 1。 延遲不必是完美的,但必須精確到 0.01% 或 100 微秒以內。 我怎樣才能做到這一點?
您需要創建循環來花時間。 您需要一個大約需要 1 秒才能執行的代碼塊,然后根據輸入的數字重復執行該塊。 因此,挑戰在於設計需要 1 秒執行時間的代碼。
讓我們用一個循環來試試:
LDA start
loop STA count
LDA count
SUB one
BRP loop
; ...other code...
one DAT 1
start DAT 999
count DAT
這個循環將有 1000 次迭代。 每次迭代有 4 條指令,因此 1000 次迭代需要 4000µs。 我們可以稍微加強代碼以使循環有更多指令,但我們離 1 秒還差得很遠,所以我們最好使用第二個循環重復執行上述操作。 該外循環需要迭代大約 250 次,因為 250*4000 = 一百萬,即 1 秒。
所以我們會有:
LDA start2
loop2 STA count2
; here starts the code we used earlier
LDA start3
loop3 STA count3
LDA count3
SUB one
BRP loop3
; end of the code we used earlier
LDA count2
SUB one
BRP loop2
; ... other code
one DAT 1
start2 DAT 249
start3 DAT 999
count2 DAT
count3 DAT
如果我們對執行的指令數量進行精確計算,那么我們得出以下結論:
這有點太多(因為開銷):偏差約為 0.1%,因此我們需要對數字進行一些調整。
但是讓我們首先通過執行外部循環來完成程序,該循環執行輸入中指定的次數:
INP
BRZ output ; output immediately!
SUB one
; a new outer loop:
loop1 STA count1
; start of what we already had:
LDA start2
loop2 STA count2
LDA start3
loop3 STA count3
LDA count3
SUB one
BRP loop3
LDA count2
SUB one
BRP loop2
; end of what we already had
LDA count1
SUB one
BRP loop1
output LDA one
OUT
HLT
one DAT 1
start2 DAT 249
start3 DAT 999
count1 DAT
count2 DAT
count3 DAT
請注意,我們添加的外部循環也有它的開銷……如果我們在該計數中包含LDA start2
,那么又是 5 條指令開銷。
因此, loop1
一次迭代需要 5 + 1001250 = 1001255。
最后,現在讓我們調整start2
和start3
值,使我們更接近start3
在電子表格中玩數字對,您會發現對於 542 次迭代, start2 = 541
和對於 460 次迭代的start3 = 459
很接近(您可以使用其他有趣的配對,結果相似)。
loop3
一次迭代中執行的指令:4loop2
一次迭代中執行的指令:5 + (460*4) = 1845loop1
一次迭代中執行的指令:5 + (542*1845) = 999995 所以我們還需要 5 條指令才能達到完美的秒數。 這很簡單……只需在loop1
的開銷中重復幾次指令即可。 所以我們最終得到了這個:
INP
BRZ output ; output immediately!
SUB one
; a new outer loop:
loop1 STA count1
LDA start2
LDA start2 ; dummy instructions to spend 5µs more...
LDA start2 ; ...
LDA start2 ; ...
LDA start2 ; ...
LDA start2 ; ...
loop2 STA count2
LDA start3
loop3 STA count3
LDA count3
SUB one
BRP loop3
LDA count2
SUB one
BRP loop2
LDA count1
SUB one
BRP loop1
output LDA one
OUT
HLT
one DAT 1
start2 DAT 541 ; the two magic numbers
start3 DAT 459 ; ...
count1 DAT
count2 DAT
count3 DAT
我們還沒有談到在loop1
之外執行的開銷。 這包括BRZ
、 SUB
(在非零輸入的情況下)和output
部分中的兩條指令( LDA
和OUT
),所以 3-4µs。
這意味着對於以下每個輸入,我們都會得到以下延遲:
input | µs from INP to OUT
------+-------------------
0 | 3
1 | 1000004
2 | 2000004
... | ...
9 | 9000004
10 | 10000004
您甚至可以通過在外循環的最后一次迭代中跳過 4 條偽指令來消除那些額外的 4 毫秒。 所以改變這個:
loop1 STA count1
LDA start2
LDA start2 ; dummy instructions to spend 5µs more...
LDA start2 ; ...
LDA start2 ; ...
LDA start2 ; ...
LDA start2 ; ...
對此:
loop1 STA count1
BRZ skip ; this branches only in the last iteration
LDA start2 ; dummy instructions to spend 4µs more...
LDA start2 ; ...
LDA start2 ; ...
LDA start2 ; ...
skip LDA start2
所以現在計時是准確的,除了輸入為0的情況。沒有辦法花少於3條指令來處理這種情況(零檢測,加載1,輸出)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.