簡體   English   中英

與Irvine組裝的RandomRange

[英]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正在划分由dxax而不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM