2013-07-25 40 views
5

首先,我對8086彙編非常新,對於我來說很難掌握知識。儘管如此,我會盡我所能。在x86 8086彙編中生成0-9範圍內的一個隨機數

我一直在試圖編寫一個代碼來生成0-9範圍內的一個隨機數。看了幾個例子和建議後,這就是我最終的結果。我沒有對檢索到的時鐘數應用任何數學函數,爲簡單起見,我也認爲這是沒有必要的。出於某些原因,我最終得到的數字少於比1,3和9等數字少6,7倍的數字。我相信這是因爲我採用了時鐘滴答的較低階數,其中數值發生了變化迅速。

我的目的是模擬一個擲骰子,後來把下面的代碼範圍改爲1-6。 我的問題是,這足以滿足我的目的嗎?或者有沒有更好的方法來做到這一點?

代碼:

RANDGEN:  ; generate a rand no using the system time 
RANDSTART: 
    MOV AH, 00h ; interrupts to get system time   
    INT 1AH  ; CX:DX now hold number of clock ticks since midnight  
       ; lets just take the lower bits of DL for a start.. 
    MOV BH, 57 ; set limit to 57 (ASCII for 9) 
    MOV AH, DL 
    CMP AH, BH ; compare with value in DL,  
    JA RANDSTART ; if more, regenerate. if not, continue... 

    MOV BH, 49 ; set limit to 48 (ASCII FOR 0) 
    MOV AH, DL 
    CMP AH, BH ; compare with value in DL 
    JB RANDSTART ; if less, regenerate. 


    ; if not, this is what we need 
    mov ah, 2h ; call interrupt to display a value in DL 
    int 21h  
RET 

答案,@johnfound:

我發現他的方法比較簡單,而且花費較少的時間來生成隨機數。他提到,只有當你需要一個隨機數時,這個工作纔有效,或者隨機數之間的間隔包括人工輸入的暫停。如果不是,這些數字將不會是隨機的(我相信由於我們最初採用的時間種子不會改變)。我的情況很好,因爲我正在模擬一個擲骰子,並且在我再次運行代碼之前我需要用戶干預(另一個擲骰)。

RANDGEN:   ; generate a rand no using the system time 
RANDSTART: 
    MOV AH, 00h ; interrupts to get system time   
    INT 1AH  ; CX:DX now hold number of clock ticks since midnight  

    mov ax, dx 
    xor dx, dx 
    mov cx, 10  
    div cx  ; here dx contains the remainder of the division - from 0 to 9 

    add dl, '0' ; to ascii from '0' to '9' 
    mov ah, 2h ; call interrupt to display a value in DL 
    int 21h  
RET  

他做了什麼: 1.我們在DX移動值斧 2.我們清除DX。 3.我們將10月10日移至CX。 4.我們將AX除以CX,因此我們得到一個0-9 Dec的餘數,存儲在DX 5中。最後,我們在DX中添加了ASCII'0'(dec 48),使它們變成ASCII'0'到'9 」。

+0

你想輸出是在1-10範圍內(如您的標題所暗示的)或0-255(如你的問題表明:* ...產生一個字節的隨機數*)?代碼看起來像是試圖在ASCII中使用'0'到'9'的範圍。 – lurker

+0

是的,正如在標題中一樣,確切的說是0-9。 – Raf

回答

6

只有當您需要一個隨機數或者隨機數之間的間隔包含人爲輸入時,此技巧纔有效。在所有其他情況下,這些數字將不會是隨機的。

如果你需要很多隨機數,那麼有不同的僞隨機數算法可用。

另一個值得注意的是,有更多的簡單的方法來獲得所需要的間隔數:

mov ax, dx 
    xor dx, dx 
    mov cx, 10  
    div cx  ; here dx contains the remainder of the division - from 0 to 9 

    add dl, '0' ; to ascii from '0' to '9' 

您可以使用此方法,當然每一個隨機數發生器。

+0

我試過你的代碼,它的工作完美無瑕。花費更少的時間來生成與我的對比。但我不完全明白一些事情。 1. xor dx,dx - 這是什麼目的? 2.添加dl,'0' - 如何通過向DL添加'0'我們實際上從0-9實現了ASCII值? – Raf

+0

我們不是給dl加0(零),而是字符「0」的ascii碼= 30h = 48。這樣,DL中的數字(從0到9)就會變成30h到39h,這就是從「0」到「9」的字符。某事xor總是= 0。 – johnfound

+0

我明白了,所以我們做了:1.我們將DX的價值轉移到了AX 2.我們清除了DX。我們將十二月十日搬到了CX。 4.我們將AX除以CX,因此我們得到一個0-9 Dec的餘數,存儲在DX 5中。最後,我們向DX添加了ASCII'0'(dec 48),使它們成爲ASCII'0'到'9' 。 好的,謝謝 – Raf

0

對於這項工作,我發現了一個較小的操作碼AAM - Ascii Adjust for Multiplication。如何操作碼的工作:

AH := AL/10 
AL := AL mod 10 

所以,這將是這樣的:

mov al, dl 
aam 
add al, '0' 
mov dl, al 
相關問題