简体   繁体   English

与Irvine组装的RandomRange

[英]RandomRange in assembly with Irvine

I am working on x86 assembly language. 我正在研究x86汇编语言。 I want to get two parameters that one is column and other one is row, using randomrange within the interval [0,5]. 我想得到两个参数,一个是列,另一个是行,在区间[0,5]内使用randomrange。 Here I tried to adjust the interval by dividing the random number by 6, and getting the number remains in DL which is remainder of the division. 在这里,我尝试通过将随机数除以6来调整间隔,并且将数字保留在DL中,这是除法的剩余部分。

I also implemented an array that holds the numbers that randomized before and jumps back to randomization if the element is already 1, which uses row*6+col to check the index, but this array is not effective yet. 我还实现了一个数组,它保存之前随机化的数字,如果元素已经为1则跳转回随机化,它使用row * 6 + col来检查索引,但是这个数组还没有效果。

I get a segmentation fault, what could be the problem? 我遇到了分段错误,可能是什么问题?

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

The irvine RandomRange function already has this functionality: irvine RandomRange函数已经具有此功能:

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

Also note that div bx is dividing the 32 bit number formed from dx : ax and not eax . 另请注意, div bx正在划分由dxax而不是eax形成的32位数。

As for the segfault, use a debugger and see where the crash is. 至于段错误,请使用调试器并查看崩溃的位置。

Irvine's RandomRange returns a number of a range of numbers. 欧文的RandomRange返回了一系列数字。 Therefore, it needs the range as argument in EAX. 因此,它需要EAX中的范围作为参数。 Consider, that EAX must not be zero, otherwise you'll get a "division by zero" exception. 考虑一下,EAX不能为零,否则你将获得“除以零”异常。 Also, the program lacks of an exit . 此外,该计划缺乏exit

RandomRange calls Irvine's Random32 which algorithm is almost the same as that of the rand() function in Microsoft's C runtime library (MSVCRT.DLL). RandomRange调用Irvine的Random32 ,该算法几乎与Microsoft的C运行时库(MSVCRT.DLL)中的rand()函数相同。 It produces a number based on another number (called "seed") which will become the new seed. 它产生一个基于另一个数字(称为“种子”)的数字,它将成为新的种子。 If you don't initialize the first seed, you will always get the same sequence of numbers. 如果您没有初始化第一个种子,您将始终获得相同的数字序列。 Initialize it once with Irvine's Randomize . 用Irvine的Randomize初始化一次。

RandomRange uses a simple modulo function to separate a number of the range: N = rand() % EAX . RandomRange使用简单的模数函数来分隔多个范围: N = rand() % EAX If the range of Random32 (0..0xFFFFFFFF) cannot evenly splitted into parts of the wished range (0..EAX-1), you get some numbers more frequently than others. 如果Random32 (0..0xFFFFFFFF)的范围无法均匀分割为所需范围(0..EAX-1)的某些部分,则会比其他数字更频繁地获得一些数字。 A formula for a better distribution of the numbers: 更好地分配数字的公式:

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

This can be easily programmed in assembly: 这可以在装配中轻松编程:

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

The whole bunch: 整个一堆:

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