[英]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.