[英]RandomRange in assembly with Irvine
我正在研究x86匯編語言。 我想得到兩個參數,一個是列,另一個是行,在區間[0,5]內使用randomrange。 在這里,我嘗試通過將隨機數除以6來調整間隔,並且將數字保留在DL中,這是除法的剩余部分。
我還實現了一個數組,它保存之前隨機化的數字,如果元素已經為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
irvine RandomRange
函數已經具有此功能:
; Returns an unsigned pseudo-random 32-bit integer
; in EAX, between 0 and n-1. Input parameter:
; EAX = n.
另請注意, div bx
正在划分由dx
: ax
而不是eax
形成的32位數。
至於段錯誤,請使用調試器並查看崩潰的位置。
歐文的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.