2013-05-19 225 views
0

我正在使用x86彙編語言。我想要得到兩個參數,一個是列,另一個是行,在區間[0,5]內使用隨機數。在這裏,我試圖通過將隨機數除以6來調整時間間隔,並且將數字保留在DL中,這是除法的剩餘部分。RandomRange與Irvine彙編

我還實現了一個數組,其中包含之前隨機化的數字,如果元素已經是1,它使用row * 6 + col檢查索引,但此數組尚未生效,則跳回隨機數。

我得到一個分段錯誤,可能是什麼問題?

TITLE Program Template  (template.asm) 


INCLUDE Irvine32.inc 
INCLUDE macros.inc 

.data 
onezero BYTE 36 DUP(0) 

row BYTE 0 
col BYTE 0 
.code 
main PROC 

_again: 

call randomrange 
mov bx, 6 
div bx 
mov row, dl 

call randomrange 
div bx 
mov col, dl 

movzx eax, row 
mov ebx, 6 
mul ebx 
movzx ecx, col 
add eax, ecx 
mov edi, eax 
mov al, 1 
cmp al, onezero[edi] 
je _again 

movzx eax, row 
call writeint 
movzx eax, col 
call writeint 

main ENDP 

END main 

回答

1

爾灣RandomRange功能已經有此功能:

; Returns an unsigned pseudo-random 32-bit integer 
; in EAX, between 0 and n-1. Input parameter: 
; EAX = n. 

還要注意的是div bx被除以從dx形成的32比特數:ax和不eax

至於segfault,請使用調試器並查看崩潰的位置。

1

Irvine的RandomRange返回一定數量的數字。因此,EAX中需要範圍作爲參數。考慮一下,EAX不能爲零,否則你會得到一個「零除」異常。另外,該程序缺少exit

RandomRange調用Irvine的Random32算法幾乎與Microsoft的C運行時庫(MSVCRT.DLL)中的rand()函數的算法相同。它會根據另一個數字(稱爲「種子」)產生一個數字,這將成爲新的種子。如果你不初始化第一個種子,你將總是得到相同的數字序列。用Irvine的Randomize初始化一次。

RandomRange使用一個簡單的模函數來區分若干個範圍:N = rand() % EAX。如果Random32(0..0xFFFFFFFF)的範圍不能均勻地分割成所需範圍的一部分(0..EAX-1),則會比其他頻率更頻繁地得到一些數字。一種用於數字的更好的分佈式:

(rand()/(RAND_MAX+1) * EAX 
=> (rand() * EAX)/(RAND_MAX+1) ; RAND_MAX is 0xFFFFFFFF (according to Irvine) 

這可以很容易地在裝配程序:

myRandomRange PROC USES EBX EDX 
    mov ebx,eax  ; maximum value 

    call Random32  ; eax = random number 

    mul ebx    ; rand() * EAX => EDX:EAX 
    mov eax, edx  ; SHL EDX:EAX,32 = Divide EDX:EAX by 0x100000000 (RAND_MAX+1) 

    ret 
myRandomRange ENDP 

的一大堆:

TITLE Program Template  (template.asm) 

INCLUDE Irvine32.inc 

.DATA 
    onezero BYTE 36 DUP(0) 
    row BYTE 0 
    col BYTE 0 

.CODE 

myRandomRange PROC USES EBX EDX 
    mov ebx,eax  ; maximum value 

    call Random32  ; eax = random number 

    mul ebx    ; rand() * EAX => EDX:EAX 
    mov eax, edx  ; SHL EDX:EAX,32 = Divide EDX:EAX by 0x100000000 (RAND_MAX+1) 

    ret 
myRandomRange ENDP 

main PROC 

    call Randomize 

    _again: 
    mov eax, 6 
    call myRandomRange 
; mov bx, 6 
; div bx 
; mov row, dl 
    mov row, al 

    mov eax, 6 
    call myRandomRange 
; div bx 
    mov col, al 

    movzx eax, row 
    mov ebx, 6 
    mul ebx 
    movzx ecx, col 
    add eax, ecx 
    mov edi, eax 
    mov al, 1 
    cmp al, onezero[edi] 
    je _again 

    movzx eax, row 
    call writeint 
    movzx eax, col 
    call writeint 

    exit 

main ENDP 

END main