Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Ассемблер _ Игровая программа

Автор: Rocket 10.03.2009 2:56

Доброго времени суток, уважаемые форумчане! smile.gif Мне нужно написать программу, которая перед началом игры произвольно устанавливает невидимую на экране метку и видимый символ "*", который перемещается по экрану с помощью стрелок. При движении символа генерируются звуковые колебания, частота которых зависит от расстояния до невидимой метки. Если метка не найдена за 4 секунды, метка перемещается в другую точку.
Мне очень эта программа напоминает металлоискатель : )
Пока что я сделал только перемещение символа "*" с помощью букв w,s,a,d.


data segment

old_cs dw ?
old_ip dw ?

symbol db ?
Pressed db 1

x db ?
y db ?

sgn db '*'
atr db 10

data ends

code segment
assume cs: code, ds: data


new_1c proc far


push ax
push bx
push ds
push es


mov ax, data
mov ds, ax


mov ax, 40h
mov es, ax
mov ax, es:[1Ch]
mov bx, es:[1Ah]
cmp bx, ax
jne get_char


jmp go_out

get_char:
mov al, es:[bx]
mov es:[1Ch], bx
mov symbol, al
inc Pressed

go_out:
pop es
pop ds
pop bx
pop ax
iret
new_1c endp

start:
mov ax, data
mov ds, ax


mov ah, 35h
mov al, 1Ch
int 21h

mov old_ip, bx
mov old_cs, es


push ds
mov dx, offset new_1c
mov ax, seg new_1c
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, data
mov es, ax

mov x,14
mov y,40

main_loop:

cmp Pressed, 0
je m1


mov Pressed, 0
cmp symbol, 30h
je q

xor ax, ax
mov al, symbol


m1: cmp al, 'w'
jne m2
dec x
jmp met

m2: cmp al, 's'
jne m3
inc x
jmp met

m3: cmp al, 'a'
jne m4
dec y
jmp met

m4: cmp al, 'd'
jne main_loop
inc y



met: xor bh, bh
mov ah, 13h
mov al, 0d
mov dh, x
mov dl, y
lea bp, sgn
mov cx, 1
mov bl, atr
int 10h

jmp main_loop

q:

push ds

mov dx, old_ip
mov ax, old_cs
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, 4C00h
int 21h
code ends
end start


Не могу понять, почему "вверх" не срабатывает с первого раза? приходится повторно нажимать "w", в результате мы поднимаеся не на одну позицию, а на две...
И как сделать какую-нибудь очистку экрана? чтоб очищать консоль и на экран выводился только один символ "*" .

Автор: volvo 10.03.2009 3:46

Цитата
И как сделать какую-нибудь очистку экрана? чтоб очищать консоль и на экран выводился только один символ "*".
Функция 06h прерывания 10h (прокрутка окна вверх) - задаешь окно, равное всему экрану, и число строк для сдвига = 0 - окно прокручивается полностью, и очищается...

Цитата
Не могу понять, почему "вверх" не срабатывает с первого раза? приходится повторно нажимать "w", в результате мы поднимаеся не на одну позицию, а на две...
Твоя программа у меня только грузит процессор на 25% и больше ничего, ВООБЩЕ ни на что не реагирует, так что тебе еще повезло, что ты хоть КАК-ТО можешь двигать звездочку.

Автор: Rocket 10.03.2009 4:33

Цитата(volvo @ 9.03.2009 23:46) *

Функция 06h прерывания 10h (прокрутка окна вверх) - задаешь окно, равное всему экрану, и число строк для сдвига = 0 - окно прокручивается полностью, и очищается...

Твоя программа у меня только грузит процессор на 25% и больше ничего, ВООБЩЕ ни на что не реагирует, так что тебе еще повезло, что ты хоть КАК-ТО можешь двигать звездочку.


Так, вот добавил очистку экрана...и проблема с двойным "вверх" ушла сама собой) но мне не понятно почему она у Вас не работает...
Вот что у меня сейчас:

data segment

old_cs dw ?
old_ip dw ?

symbol db ?
Pressed db 1

x db ?
y db ?

sgn db '*'
atr db 10

data ends

code segment
assume cs: code, ds: data

clrscn proc

push ax
push bx
push ds
push es

mov cl, 0
mov ch, 0
mov dl, 80
mov dh, 25

xor ax,ax
mov al,0

xor bx, bx
mov bh, atr

int 10h

pop es
pop ds
pop bx
pop ax

ret

clrscn endp




new_1c proc far


push ax
push bx
push ds
push es


mov ax, data
mov ds, ax


mov ax, 40h
mov es, ax
mov ax, es:[1Ch]
mov bx, es:[1Ah]
cmp bx, ax
jne get_char


jmp go_out

get_char:
mov al, es:[bx]
mov es:[1Ch], bx
mov symbol, al
inc Pressed

go_out:
pop es
pop ds
pop bx
pop ax
iret
new_1c endp

start:
mov ax, data
mov ds, ax


mov ah, 35h
mov al, 1Ch
int 21h

mov old_ip, bx
mov old_cs, es


push ds
mov dx, offset new_1c
mov ax, seg new_1c
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, data
mov es, ax

mov x,14
mov y,40

main_loop:

;call clrscn

cmp Pressed, 0
je m1


mov Pressed, 0
cmp symbol, 30h
je q

xor ax, ax
mov al, symbol


m1: cmp al, 'w'
jne m2
dec x
jmp met

m2: cmp al, 's'
jne m3
inc x
jmp met

m3: cmp al, 'a'
jne m4
dec y
jmp met

m4: cmp al, 'd'
jne main_loop
inc y



met:
call clrscn
xor bh, bh
mov ah, 13h
mov al, 0d
mov dh, x
mov dl, y
lea bp, sgn
mov cx, 1
mov bl, atr
int 10h

jmp main_loop

q:

push ds

mov dx, old_ip
mov ax, old_cs
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, 4C00h
int 21h
code ends
end start



Вроде никаких хитростей нет, почему не запускается не понятно.
Просто сейчас начинается реально трудная вещь, которую я ума не приложу как делать, то есть генерация звука определённой частоты, которая зависит от расстояния до невидимой точки... как вообще эту точку произволно-то ставить? в ассеблере есть что-то вроде рандома?

Автор: andriano 10.03.2009 12:31

1. Звук генерится посредством 53 таймера, причем его прохождение на динамик еще надо разрешить. Конкретных номеров портов навскидку не помню - давно не программировал под DOS.
2. х86 процессор не имеет аппаратных средств для генерации случайных чисел. Это ответ на твой вопрос - есть ли в ассемблере рандом. Но можно сделать программно генератор псевдослучайных чисел. Например, конгруэнтный. А инициализировать его (аналог randomize) чем-то, связанным с текущим временем. Хотя бы содержимым ячейки 0040:006c.

Автор: TarasBer 10.03.2009 18:50

Цитата(andriano @ 10.03.2009 8:31) *

2. х86 процессор не имеет аппаратных средств для генерации случайных чисел. Это ответ на твой вопрос - есть ли в ассемблере рандом. Но можно сделать программно генератор псевдослучайных чисел. Например, конгруэнтный. А инициализировать его (аналог randomize) чем-то, связанным с текущим временем. Хотя бы содержимым ячейки 0040:006c.


Я приведу дельфийскую реализацию рандома.

procedure _RandInt;
asm
PUSH EBX
XOR EBX, EBX
IMUL EDX,[EBX].RandSeed,08088405H
INC EDX
MOV [EBX].RandSeed,EDX
MUL EDX
MOV EAX,EDX
POP EBX
end;



Это для 32х-разрядного проца. Смысл в том, что число RandSeed умножается на спец.константу $08088405, и увеличивается на 1. Так получается новое число RandSeed. А для того, чтобы из этого рандсида извлечь число, этот рандсид умножается на границу. И то, что вылезло за пределы 32 бит (оно автоматически пихается в регистр EDX) - и выдаётся как результат функции.
Для 16-битного проца, думаю, можно сделать аналогично, надо только знать, куда команда MUL пихает результат, а куда - то, что вылезло за пределы. И какова спец.константа для 16-битного случая - я не знаю.

Автор: TarasBer 10.03.2009 20:00

А турбо-паскальный рандом такой же. Я не нашёл менее порнушного способа перемножить два 32-битных числа на 16-битном асме, так что вот, процедура оформлена по-паскалевски, но оформите её по-асмовски сами.


function RAsm(w: word): word; assembler;
asm
mov dx, 8405h
mov ax, word ptr RS
mul dx
mov cx, ax
mov bx, dx

mov dx, 0808h
mov ax, word ptr RS
mul dx
add bx, ax

mov dx, 8405h
mov ax, word ptr RS+2
mul dx
add bx, ax

inc cx
jno @
inc(bx)
@:
mov word ptr RS, cx
mov word ptr RS+2, bx

mov dx, bx
mov ax, w
mul dx
mov ax, dx
end;



RS - это RandSeed
При сравнении со стандартным рандомом получилось только одно отклонение - для очень больших w стандартный рандом почему-то даёт на 1 больше, чем мой.

Автор: volvo 11.03.2009 0:06

По поводу генерации звуков - когда-то 7in на одном из форумов приводил вот такие процедуры:

Цитата(7in)
; Процедура Sound: генерация звука
; Вход: AX = частота звука (Гц)
Sound proc
xchg bx, ax ; Частота
mov dx, 12h ; (DX,AX)=1193181
cmp bx, dx ; Если Bx <= 18Гц, то выход
jbe Done ; Чтобы избежать переполнения
in al, 61h ; Порт РВ
or al, 3 ; Установить биты 0-1
out 61h, al
mov al, 10110110b ; Управляющее слово таймера:
; канал 2, режим 3, двоичное слово
out 43h, al ; Вывод в регистр режима
mov ax, 34DDh
div bx ; AX=(DX:AX)/BX
out 42h, al ; Младший байт счетчика
mov al, ah
out 42h, al ; Старший байт счетчика
Done:
ret
Sound endp

;-------------------------------------------------;

; Процедура NoSound: выключение звука
NoSound proc
in al, 61h ; Порт РВ
and al, not 3 ; Сброс битов 0-1
out 61h, al
ret
NoSound endp
У него же были и Randomize + Random, но поскольку кое-что тебе уже подсказали по поводу случайных чисел, то повторяться не буду...

Автор: Rocket 13.03.2009 1:32

Цитата(volvo @ 10.03.2009 20:06) *

По поводу генерации звуков - когда-то 7in на одном из форумов приводил вот такие процедуры:
У него же были и Randomize + Random, но поскольку кое-что тебе уже подсказали по поводу случайных чисел, то повторяться не буду...


Использую эту процедуру в программе, динамик издаёт однократный треск. А как сделать именно дискретное "пиканье" через всё выполнение программы? и чтоб частота этого "пиканья" зависела от расстояния до невидимой точки...?

Автор: andriano 13.03.2009 1:52

Цитата(Rocket @ 12.03.2009 21:32) *

Использую эту процедуру в программе, динамик издаёт однократный треск. А как сделать именно дискретное "пиканье" через всё выполнение программы? и чтоб частота этого "пиканья" зависела от расстояния до невидимой точки...?

Повесить на прерывание таймера (кажется 1с) управление режимом генерации звука. Основная программа вычисляет параметры (например, интервал между "бипами" в "тиках", т.е. в 1/18.2 сек), а вызываемая по таймеру процедура в нужные моменты включает и выключает динамик.

Автор: Rocket 15.05.2009 0:26

После долго перерыва возвращаюсь к выполнению этого задания (с COM портами вроде разобрался smile.gif )
Решил систематизировать эту задачку,т.к. довольно она для меня трудоёмкая, сложная и значимая. Так вот, что нужно:
1. Произвольно ставить невидимую точку;
2. Перемещать курсор (значок *);
3. Генерировать звук определённой частоты;
4. Каждые 4 сек менять положение невидимой точки.
План минимум, да и вообще основной - это первые три пункта... 2-ой я реализовал- вроде как перемещаю.
Начну с randoma. Уже была дана реализация:


function RAsm(w: word): word; assembler;
asm
mov dx, 8405h
mov ax, word ptr RS
mul dx
mov cx, ax
mov bx, dx

mov dx, 0808h
mov ax, word ptr RS
mul dx
add bx, ax

mov dx, 8405h
mov ax, word ptr RS+2
mul dx
add bx, ax

inc cx
jno @
inc(bx)
@:
mov word ptr RS, cx
mov word ptr RS+2, bx

mov dx, bx
mov ax, w
mul dx
mov ax, dx
end;


Как задать интервал для случайных чисел, минимальное и максимальное значение? Что означает переменная RS (RandSeed) и w?

Автор: volvo 15.05.2009 4:33

Цитата
Как задать интервал для случайных чисел
Как обычно: функция генерации случайного числа от 0 до W у тебя есть, вот и напиши еще одну - для генерации числа в интервале A .. B:
(Rnd(B - A + 1) + A) даст тебе число в интервале этом интервале.

Цитата
Что означает переменная RS (RandSeed)
Это значение, которое используется для инициализации генератора псевдослучайных чисел. При инициализации одним и тем же числом, получишь одинаковые последовательности ПСЧ.

Автор: Rocket 15.05.2009 19:49

Цитата(volvo @ 15.05.2009 1:33) *

Как обычно: функция генерации случайного числа от 0 до W у тебя есть, вот и напиши еще одну - для генерации числа в интервале A .. B:
(Rnd(B - A + 1) + A) даст тебе число в интервале этом интервале.

Это значение, которое используется для инициализации генератора псевдослучайных чисел. При инициализации одним и тем же числом, получишь одинаковые последовательности ПСЧ.


Оформил функцию под ассемблер:

data segment
RS dw 0
w dw 80
r dw ?
data ends

code segment
assume cs: code, ds: data

writeDEC proc

push ax
push bx
push cx
push dx

xor cx, cx
mov bx, 10

next_digit:
xor dx, dx
div bx
push dx
inc cx
or ax, ax
jnz next_digit

next_char:
pop ax
add al, '0'
mov dx, ax
mov ah, 02h
int 21h
loop next_char

pop dx
pop cx
pop bx
pop ax
ret
writeDEC endp

Rand proc

push ax
push bx
push cx
push dx



mov dx, 8405h
mov ax, word ptr RS
mul dx
mov cx, ax
mov bx, dx

mov dx, 0808h
mov ax, word ptr RS
mul dx
add bx, ax

mov dx, 8405h
mov ax, word ptr RS+2
mul dx
add bx, ax

inc cx
jno @
inc(bx)
@:
mov word ptr RS, cx
mov word ptr RS+2, bx

mov dx, bx
mov ax, w
mul dx
mov ax, dx
mov r, ax


pop dx
pop cx
pop bx
pop ax

ret
Rand endp

start:
mov ax, data
mov ds, ax

call Rand
mov ax, r
call writeDEC

mov ax, 4C00h
int 21h
code ends
end start


Вывожу значения с помощью процедуры writeDec. Всё время выводится одно и тоже число: 4298, и оно явно не лежит в интервале от 0 до 80... С чем это связано? Как исправить?

Автор: Rocket 16.05.2009 4:13

В интернете как-то мало материала по этой теме, так что необходимо разобраться в данной реализации random'а на ассемблере... Что не правильно в реализации Rand в предыдущем сообщении? Пожалуйста подскажите.

Автор: Rocket 19.05.2009 0:29

Что-то вопрос о random'е намертво забуксовал... Перейду к другой части задачи: генерация звука определенной частоты. Вот программы, в которой я передвигаю курсор, а его движение сопровождается нотой до (я эту ноту могу часами держать(с) )


data segment

old_cs dw ?
old_ip dw ?

symbol db ?
Pressed db 1

x db ?
y db ?

sgn db '*'
atr db 10



data ends

code segment
assume cs: code, ds: data

clrscn proc

push ax
push bx
push ds
push es

mov cl, 0
mov ch, 0
mov dl, 80
mov dh, 25

xor ax,ax
mov al,0

xor bx, bx
mov bh, atr

int 10h

pop es
pop ds
pop bx
pop ax

ret

clrscn endp


Sound proc

push ax
push bx
push ds
push es

mov bx,ax
mov ax,word ptr cs:freq
mov dx,word ptr cs:freq+2
div bx
mov bx,ax
in al,61h
nop
nop
nop
or al,3
out 61h,al
nop
nop
nop
mov al,10110110b
out 43h,al
nop
nop
nop
mov al,bl
out 42h,al
nop
nop
nop
mov al,bh
out 42h,al
nop
nop
nop
pop es
pop ds
pop bx
pop ax
ret
freq dd 1193180

Sound endp

NoSound proc

push ax
push bx
push ds
push es

in al,61h
nop
nop
nop
and al,11111100b
out 61h,al
nop
nop
nop
pop es
pop ds
pop bx
pop ax
ret
NoSound endp

new_1c proc far


push ax
push bx
push ds
push es


mov ax, data
mov ds, ax


mov ax, 40h
mov es, ax
mov ax, es:[1Ch]
mov bx, es:[1Ah]
cmp bx, ax
jne get_char


jmp go_out

get_char:
mov al, es:[bx]
mov es:[1Ch], bx
mov symbol, al
inc Pressed

go_out:
pop es
pop ds
pop bx
pop ax
iret
new_1c endp

start:
mov ax, data
mov ds, ax


mov ah, 35h
mov al, 1Ch
int 21h

mov old_ip, bx
mov old_cs, es


push ds
mov dx, offset new_1c
mov ax, seg new_1c
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, data
mov es, ax

mov x,14
mov y,40




main_loop:

;call clrscn

cmp Pressed, 0
je m1


mov Pressed, 0
cmp symbol, 30h
je q

xor ax, ax
mov al, symbol


m1: cmp al, 'w'
jne m2
dec x
jmp met

m2: cmp al, 's'
jne m3
inc x
jmp met

m3: cmp al, 'a'
jne m4
dec y
jmp met

m4: cmp al, 'd'
jne main_loop
inc y



met:
push ax
xor ax,ax
mov ax, 262
call Sound


pop ax

call clrscn
xor bh, bh
mov ah, 13h
mov al, 0d
mov dh, x
mov dl, y
lea bp, sgn
mov cx, 1
mov bl, atr
int 10h

jmp main_loop

q:

push ds

mov dx, old_ip
mov ax, old_cs
mov ds, ax
mov ah, 25h
mov al, 1Ch
int 21h
pop ds

mov ax, 4C00h
int 21h
code ends
end start


Как сделать "пиканье"? то есть, что бы звук включался и отключался в определенные моменты, а так же ускорялся, либо замедлялся

Автор: volvo 22.05.2009 16:16

Цитата
Что-то вопрос о random'е намертво забуксовал...
Ничего не забуксовало... Просто до ассемблера надо еще добраться... Вот тут есть пример работающего Random-а, только что проверил:
http://www.programmersheaven.com/mb/SourceShare/125651/125651/random-values/?S=B20000 (см. последнюю вставку кода, вызывать - так:

start:
mov ax, data
mov ds, ax
mov es, ax

call RandomSeed

mov cx, 0
mov dx, 50
call RandomRange ; Random в интервале [0 .. 50]

call writeDEC

mov ax, 4C00h
int 21h

)

Автор: volvo 22.05.2009 18:44

Цитата
Как сделать "пиканье"? то есть, что бы звук включался и отключался в определенные моменты
Вероятно, в те моменты, когда звук не нужен, его надо отключать, используя NoSound, который ты написал, а зачем - непонятно...
Цитата
а так же ускорялся, либо замедлялся
Кто "ускорялся" или "замедлялся"? Звук? Он не может замедляться и ускоряться. Он может только быть или нет. Может быть, тебе надо более высокие звуки при приближении к цели? Или просто уменьшить интервалы между выключением звука и его следующим включением...

Автор: Rocket 22.05.2009 19:36

Цитата(volvo @ 22.05.2009 15:44) *

Вероятно, в те моменты, когда звук не нужен, его надо отключать, используя NoSound, который ты написал, а зачем - непонятно...
Кто "ускорялся" или "замедлялся"? Звук? Он не может замедляться и ускоряться. Он может только быть или нет. Может быть, тебе надо более высокие звуки при приближении к цели? Или просто уменьшить интервалы между выключением звука и его следующим включением...

Да, мне нужно уменьшать или увеличивать интервалы между включением\отключением звука. Делать это нужно через программирование таймера? Ещё есть варианты?

Автор: volvo 22.05.2009 19:58

Цитата
Ещё есть варианты?
Сомневаюсь... Какие ж варианты еще? А что не нравится с программированием таймера?

Автор: Rocket 22.05.2009 20:06

Цитата(volvo @ 22.05.2009 16:58) *

Сомневаюсь... Какие ж варианты еще? А что не нравится с программированием таймера?

В программирование таймера мне всё нравится, я просто не знаю как его реализовать...

Автор: volvo 22.05.2009 20:23

Очень просто... Вот тут есть пример практически того, что тебе надо:
http://www.fastgraph.com/makegames/sidescroller/chapt12.html#S17

Автор: Rocket 22.05.2009 20:43

Цитата(volvo @ 22.05.2009 17:23) *

Очень просто... Вот тут есть пример практически того, что тебе надо:
http://www.fastgraph.com/makegames/sidescroller/chapt12.html#S17


Спасибо, буду разбираться!

volvo, Вы не могли бы посмотреть мой вопрос о random'е в этой теме за 15.05.2009 16:49 ?

Автор: volvo 22.05.2009 21:54

Почему я? Кто привел тебе этот код, тот пускай и смотрит, почему код не работает. Все на самом деле гораздо проще делается. Я тебе уже привел ссылку на работающий код. Если тот код тебе не нравится - то (с учетом того, что координаты у тебя все равно однобайтовые, в пределах от 0 до 80) можешь попробовать вот эту процедуру:

RS dw 0
range db 80

random proc
mov ax, RS
mov dx, 8405h
mul dx
inc ax
mov dx, ax
mov RS, ax
mov cl, range
sub cl, 2
inc cx
xor dx, dx
div cx
mov ax, dx ; в AX - случайное число...
ret
random endp
Получи в одной программе несколько чисел:
	call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h
, и убедись, что они все разные, и ни одно не превышает 80. Но вот при разных запусках все последовательности будут одинаковыми, потому что RS не изменяется, он при старте программы всегда один и тот же. Чтобы получить разные последовательности - занеси в RS при старте значение системного таймера...

Автор: Rocket 22.05.2009 22:38

Цитата(volvo @ 22.05.2009 18:54) *
Чтобы получить разные последовательности - занеси в RS при старте значение системного таймера...


Заношу в RS секунды и милисекунды системного времени:

data segment

RS dw ?
range db 80
CR db 13,10,"$"
data ends

code segment
assume cs: code, ds: data

writeDEC proc

push ax
push bx
push cx
push dx

xor cx, cx
mov bx, 10

next_digit:
xor dx, dx
div bx
push dx
inc cx
or ax, ax
jnz next_digit

next_char:
pop ax
add al, '0'
mov dx, ax
mov ah, 02h
int 21h
loop next_char

pop dx
pop cx
pop bx
pop ax
ret
writeDEC endp

GetTime proc

push ax
push cx
push dx

xor ax,ax
xor cx,cx
xor dx,dx

mov ah, 2ch
int 21h

mov al, dh
mov ah, dl
mov RS, ax
pop dx
pop cx
pop ax
ret
GetTime endp

random proc

push ax
push bx
push cx
push dx



mov ax, RS
mov dx, 8405h
mul dx
inc ax
mov dx, ax
mov RS, ax
mov cl, range
sub cl, 2
inc cx
xor dx, dx
div cx
mov ax, dx ; в AX - случайное число...



pop dx
pop cx
pop bx
pop ax

ret
random endp

start:
mov ax, data
mov ds, ax

call GetTime
mov ax, RS
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

mov ax, 4C00h
int 21h
code ends
end start


Теперь всё время печатается 36 четыре раза. Хотя RS разное каждый раз. Такой же результат был и сначала. Что сейчас не так?

Автор: volvo 22.05.2009 23:05

Цитата
Такой же результат был и сначала.
То есть, у тебя не отрабатывает вот это (переименовать в *.ASM):
Прикрепленный файл  rand2.pas ( 1.03 килобайт ) Кол-во скачиваний: 326

вот с таким результатом:
Прикрепленное изображение
? blink.gif Ну, тогда я не знаю, что у тебя творится...

Добавлено через 17 мин.
P.S. Соответственно,
Прикрепленный файл  rand3.pas ( 1.09 килобайт ) Кол-во скачиваний: 381

выдает
F:\Asm30>rand3
48
33
54
15

F:\Asm30>rand3
54
15
28
61

F:\Asm30>rand3
43
40
57
78
Поверишь, или еще один скриншот сделать?

Автор: Rocket 23.05.2009 1:21

Цитата(volvo @ 22.05.2009 20:05) *
То есть, у тебя не отрабатывает вот это

Спасибо! Всё и у меня заработало smile.gif

Автор: Rocket 23.05.2009 2:02

Цитата(volvo @ 22.05.2009 18:54) *

Почему я? Кто привел тебе этот код, тот пускай и смотрит, почему код не работает. Все на самом деле гораздо проще делается. Я тебе уже привел ссылку на работающий код. Если тот код тебе не нравится - то (с учетом того, что координаты у тебя все равно однобайтовые, в пределах от 0 до 80) можешь попробовать вот эту процедуру:
RS dw 0
range db 80

random proc
mov ax, RS
mov dx, 8405h
mul dx
inc ax
mov dx, ax
mov RS, ax
mov cl, range
sub cl, 2
inc cx
xor dx, dx
div cx
mov ax, dx ; в AX - случайное число...
ret
random endp
Получи в одной программе несколько чисел:
	call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h

call random
xor ah, ah
call writeDEC
lea dx, CR
mov ah, 9
int 21h
, и убедись, что они все разные, и ни одно не превышает 80. Но вот при разных запусках все последовательности будут одинаковыми, потому что RS не изменяется, он при старте программы всегда один и тот же. Чтобы получить разные последовательности - занеси в RS при старте значение системного таймера...


volvo, случайное число помещается в ax, то есть word, а как к byte'ам привести? я что-то запамятовал

Автор: volvo 23.05.2009 4:16

Цитата
случайное число помещается в ax, то есть word, а как к byte'ам привести?
AL взять и использовать, вот и байт тебе...

Автор: TarasBer 23.05.2009 23:35

Цитата(volvo @ 22.05.2009 18:54) *

Почему я? Кто привел тебе этот код, тот пускай и смотрит, почему код не работает.


Не знаю, у меня всё работает. Возможно, при переводе из Паскаля в Асм есть ещё какие-то тонкости.