[Logo] Форум DL
  [DL]  Back to home page 
Forum Index ->Учебный процесс ГГУ/СШ 27 ->Проектирование цифровых систем 1, 2, 3
Author Message
Evgeniy Bychkov

Topics: 0
Messages: 59

My Profile
у меня в процессе отработки пропуска возник вопрос. у меня было задание остортировать два числа(у каждого длина 1 байт).
сначала я использовал алгортим такого вида :
;это не код выполняющий задание, а лишь пример кода который
;(как я предполагал) должен был сработать
	JMP BEGIN
a	db	255
b	db	0
biggest	db	0
BEGIN:
	mov	al , a
	cmp 	al , b
	jg 	STEP
	mov	al , b
	mov 	biggest, al
	jmp	endStep
STEP:	mov	biggest , al
endStep:

ENDS: JMP ENDS ;$E

однако, если сравнивать таким образом, то некорректно сравнивается число 255 (которое есть в тестах)
если же использовать функцию CBW к числу 255, то изменяется значение в регистре. единственный вариант, который пришел мне в голову, это после инструкции CBW явно обнулить значение в регистре AH.таким образом алгоритм стал выглядеть :
JMP BEGIN
a	db	255
b	db	0
x	db	1
y	db	0
BEGIN:	mov 	al , b
	cbw
	mov 	ah , 0
	mov 	bx , ax
	mov 	al , a
	cbw
	mov 	ah , 0

	cmp 	ax , bx
	jg 	MET
	mov 	x , bl
	mov 	y , al
	jmp	ends
MET:
	mov 	x , al
	mov 	y , bl
ends:



ENDS: JMP ENDS ;$E

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

UPD:
после некоторого поиска оказалось что для знаковой и беззнаковой математики используются разные метки перехода. если кто-то из тех, кто наткнется на этот пост будет в них нуждаться, то вот они :
+--------+------------------------------+-------------+--------------------+
|Instr   | Description                  | signed-ness | Flags              |
+--------+------------------------------+-------------+--------------------+
| JB/    | Jump if below                | unsigned    | CF = 1             |
| JNAE/  | Jump if not above or equal   |             |                    |
| JC     | Jump if carry                |             |                    |
+--------+------------------------------+-------------+--------------------+
| JNB/   | Jump if not below            | unsigned    | CF = 0             |
| JAE/   | Jump if above or equal       |             |                    |
| JNC    | Jump if not carry            |             |                    |
+--------+------------------------------+-------------+--------------------+
| JBE/   | Jump if below or equal       | unsigned    | CF = 1 or ZF = 1   |
| JNA    | Jump if not above            |             |                    |
+--------+------------------------------+-------------+--------------------+
| JA/    | Jump if above                | unsigned    | CF = 0 and ZF = 0  |
| JNBE   | Jump if not below or equal   |             |                    |
+--------+------------------------------+-------------+--------------------+

и еще англ доки : http://unixwiz.net/techtips/x86-jumps.html
Mihail Dolinskiy

Topics: 1557
Messages: 37063

My Profile
Молодец, так и должен поступать настоящий программист для решения проблем.
Кстати, следующая лекция у нас по теме "Таблица команд", где и об этом тоже будет рассказываться.

Маленькое замечание
для знаковой и беззнаковой математики используются разные метки перехода 

Разные инструкции сравнения,
которые, в частности, по-разному трактуют число 1111 1111 в байте
Инструкции сравнения JLE и проч., о которых я Вам уже рассказывал, считают, что это число -1.
А инструкции, JAE и проч., о которых буду рассказывать, считают, что это число 255.
Anna Golosova

Topics: 0
Messages: 28

My Profile
Добрый день! На лекции 30.03.2017 у нашей группы возникли проблемы с задачей.
Ссылка на задачу - http://dl.gsu.by/task.jsp?nid=1658556&cid=1041

Когда задача не проходила, подключили тесты из протокола, в программе winter тесты не проходили, но при доскональном списывании с подсказки к задаче на dl задачу приняли(при этом в winter программа все равно не проходила)

Еще один вопрос: В тестах символом конца строки принято считать символ '#', а в подсказке к решению предлагают использовать символ '!'.

Тесты из протокола:
Report = report.txt
StopOnError = true
Statistics = false
WatchReport = false
ShowReport = true

[1]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: ABCDEfghi#

RES dec[2]: 2

[2]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: BCDBCDBCDB#

RES hex[2]: 0000

[3]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: AIEOUAIEOB#

RES hex[2]: 0009

[4]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: TESTWORD#

RES hex[2]: 0002

[5]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: AEIOUY#

RES dec[2]: 5

[6]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: BCDFGHJKLMNPQRSTVWXZ#

RES dec[2]: 0

[7]
Cycles = 1000
CheckCycles = true
Segment - 0
Offset - 0


IN_STR str: #

RES dec[2]: 0


Исходник программы, которая прошла на dl:
jmp begin
IN_STR db 'ABCDEfghkjgsdvcksdvckjsdci#     '
RES    dw 0
       db 0DH, 0AH
begin:
 lea bx, IN_STR
 mov cx, 0
 mov bp, 0
 dec bx
 mov al, '!'
len:
 inc bx
 inc cx
 cmp al, [bx]
 jne len

 dec cx
 dec bx
cikl:
 mov al, [bx]
 cmp al, 'A'
 je inca
 cmp al, 'I'
 je inca
 cmp al, 'E'
 je inca
 cmp al, 'O'
 je inca
 cmp al, 'U'
 je inca
 dec bx
 loop cikl
 jmp fin
inca:
 inc bp
 dec bx
 jmp cikl
fin: mov RES, bp
HALF: jmp HALF ;$E

Anna Golosova

Topics: 0
Messages: 28

My Profile
Еще раз добрый день!
Возникла похожая проблема с задачей по ссылке http://dl.gsu.by/task.jsp?nid=1658558&cid=1041

Забрала тесты из протокола, в программе winter не проходит даже первый тест. А в dl задача набирает по максимуму.

Тесты:
Report = report.txt
StopOnError = true
Statistics = false
WatchReport = false
ShowReport = false

[TEST1]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: ABSDABC#

OUT1 dec[2]: 2

[TEST2]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: ABSDABCABW#

OUT1 dec[2]: 3

[TEST3]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: BASDE#

OUT1 dec[2]: 0

[TEST4]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: ABafABAB#

OUT1 dec[2]: 3

[TEST5]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: BAbabaBBAbabAb#

OUT1 dec[2]: 0

[TEST6]
Cycles = 1
CheckCycles = true
Segment - 0
Offset - 0


IN1 str: dsEABBArtEA#

OUT1 dec[2]: 1



Исходник программы, которая набрала 100/100

jmp begin
IN1 db 'ABAASBAAB#                           '
OUT1 dw 0
begin:
  lea bx, IN1
  mov dx, 0
cikl:
  mov al, [bx]
  cmp al, '#'
  je ends
  cmp al, 'A'
  jne cont1
  inc dx
  jmp cont
  cont1:
  cmp al, 'B'
  jne cont2
  cmp dx, 0
  je cont
  inc OUT1
  cont2:
  mov dx, 0
  cont:
  inc bx
  jmp cikl

ends: jmp ends ;$E

Есть мысли, что это связано с начальной инициализацией входной строки IN1. Если в начале программы написать

IN1 db 'ABAASBAAB#' - первый тест проходит, а во второй выдает сообщение
[TEST1]: Тест прошел.
[TEST2]: Размерность массива IN1 должна быть не менее 11 байтов.

Если же написать
IN1 db 'ABAASBAAB#____________________________' - первый тест не проходит в программе winter, а на dl проходят все
Igor Korshunov

Topics: 6
Messages: 1531

My Profile


Анна Голосова:

Добрый день! На лекции 30.03.2017 у нашей группы возникли проблемы с задачей.
Ссылка на задачу - http://dl.gsu.by/task.jsp?nid=1658556&cid=1041

Когда задача не проходила, подключили тесты из протокола, в программе winter тесты не проходили, но при доскональном списывании с подсказки к задаче на dl задачу приняли(при этом в winter программа все равно не проходила)

Еще один вопрос: В тестах символом конца строки принято считать символ '#', а в подсказке к решению предлагают использовать символ '!'.
 

Пример решения исправлен.

1. Неправильный символ конца строки '!'. Длина строки получалась больше реальной (в зависимости когда попадался '!' в неинициализированной памяти). Соответственно иногда получались неправильные результаты, если до символа '!' встречались гласные буквы.

2. В случае пустой строки в СХ оказывался ноль, а это означало длину строки 65536 байт. Добавил проверку и переход в конец в этом случае.
Po-21 karpenko

Topics: 0
Messages: 1

My Profile
http://dl.gsu.by/task.jsp?nid=1658612&cid=1041
Я взял тесты, подключил, все тесты пройдены.
Отправляю на проверку, выдаёт ошибку в первом тесте.
Решение найдено: не хватало ";$e".
jmp 	begin
a	dw	2
b	dw	-3
c	db	-5
d	db	4
RES	dw	0

begin:
	mov 	bx,4
	cmp	a,bx
	je	met1
	mov	ax,a
	add	ax,b
	mov	bx,ax
	mov	al,c
	imul	d
	mov	cx,0
	cmp	ax,cx
	jl	men
	jg	bol
back:
	mov	ax,bx
	cwd
	idiv	a
	mov	RES,ax
	jmp	halt
met1:
	mov	al,c
	cbw
	cwd
	idiv	a
	mov	bx,ax
	mov	al,d
	cbw
	mov	cx,ax
	mov	ax,b
	cwd
	idiv	cx
	add	ax,bx
	mov	bx,ax
	mov	al,c
	cbw
	imul	a
	sub	bx,ax
	mov	RES,bx

halt:
	jmp	halt

men:	add	bx,1
	jmp 	back
bol:	add	bx,-1
	jmp	back

Report = report.txt
StopOnError = true
Statistics = false
WatchReport = false
ShowReport = true

[test 1]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 5
b sgn[2]: 24
c sgn[1]: 255
d sgn[1]: 249

res sgn[2]: 5

[test 2]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 2
b sgn[2]: 65533
c sgn[1]: 251
d sgn[1]: 4

res sgn[2]: 0

[test 3]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 3
b sgn[2]: 65535
c sgn[1]: 9
d sgn[1]: 253

res sgn[2]: 1

[test 4]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 3
b sgn[2]: 2
c sgn[1]: 2
d sgn[1]: 249

res sgn[2]: 2

[test 5]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 4
b sgn[2]: 6
c sgn[1]: 8
d sgn[1]: 3

res sgn[2]: 65508

[test 6]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 4
b sgn[2]: 65533
c sgn[1]: 4
d sgn[1]: 1

res sgn[2]: 65518

[test 7]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 2
b sgn[2]: 4
c sgn[1]: 0
d sgn[1]: 243

res sgn[2]: 3

[test 8]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 4
b sgn[2]: 8000
c sgn[1]: 80
d sgn[1]: 2

res sgn[2]: 3700

[test 9]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 1
b sgn[2]: 12000
c sgn[1]: 255
d sgn[1]: 255

res sgn[2]: 12000

[test 10]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 1
b sgn[2]: 4000
c sgn[1]: 1
d sgn[1]: 1

res sgn[2]: 4000

[test 11]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 1
b sgn[2]: 5000
c sgn[1]: 255
d sgn[1]: 1

res sgn[2]: 5002

[test 12]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: 1
b sgn[2]: 13333
c sgn[1]: 1
d sgn[1]: 0

res sgn[2]: 13334

[test 13]
Cycles = 1000
CheckCycles = false
Segment - 0
Offset - 0


a sgn[2]: -1000
b sgn[2]: 6999
c sgn[1]: -10
d sgn[1]: 11

res sgn[2]: -6

Gurskiy-stoma

Topics: 0
Messages: 1

My Profile
Командные олимпиады\Программирование\Подготовка к контрольному срезу\Контроль\Ассемблер\2 - "Задача №7" 5599

http://dl.gsu.by/task.jsp?nid=1658612&cid=1041

Ошибка исполнения программы: Integer Owerflow.
В метке equal, операция idiv bl (Деление слова на байт)
Решение найдено:

mov al,d
cbw ;расширяем до слова
mov bx,ax
mov ax,b
cwd ;расширяем до двойного слова
idiv bx ;выполняем деление слово на слово



	jmp	begin
a	dw	4
b	dw	8000
c	db	80
d	db	2
RES	dw	0
begin:
	mov	ax,a
	cmp	ax,4
	je	equal
	mov	al,c
	imul	d	;ax=c*d
	cmp	ax,0
	je	e1
	jg	e2
	mov	cx,-1
	jmp	nequal
e1:
	mov	cx,0
	jmp	nequal
e2:
	mov	cx,1
nequal:
	mov	ax,a
	add	ax,b
	sub	ax,cx	;ax=a+b-sign(c*d)
	mov	cx,a
	cwd
	idiv	cx
	jmp	fin
equal:
	mov	al,c
	cbw
	cwd
	mov	bx,a
	idiv	bx
	mov	cx,ax
	mov	ax,b
	mov	bl,d
	idiv	bl
	add	cx,ax	;cx=c/a+b/d
	mov	al,c
	cbw
	imul	a
	sub	cx,ax
	mov	ax,cx
fin:
	mov	RES,ax
halt:
	jmp	halt ;$E

Igor Korshunov

Topics: 6
Messages: 1531

My Profile


Анна Голосова:

Возникла похожая проблема с задачей по ссылке http://dl.gsu.by/task.jsp?nid=1658558&cid=1041

Забрала тесты из протокола, в программе winter не проходит даже первый тест. А в dl задача набирает по максимуму.
 



Гурский-Стома:

Командные олимпиады\Программирование\Подготовка к контрольному срезу\Контроль\Ассемблер\2 - "Задача №7" 5599

http://dl.gsu.by/task.jsp?nid=1658612&cid=1041

Ошибка исполнения программы: Integer Owerflow.
 


Если программа ведет себя локально и при тестировании на DL по-разному возможны такие варианты:

1. Не тот тест. Проверить что подключен именно нужный тест.

2. Тест подключен неверно или испорчен. Еще раз скопировать тест с DL и подключить его в WInter.

3. Ошибка WInter. В этом случае по окончании тестирования выполнение программы останавливается не на последнем операторе, а где-то в середине, где останова быть не должно. Помогает перезапуск WInter.

4. Программа использует неинициализированную память, переменные или регистры. В этом случае при одних и тех же входных данных программа может выдавать разные ответы. Несколько раз запустить тестирование сняв флажок "останавливать при ошибке", если некоторые тесты то проходят, то нет нужно искать где в программе используется неинициализированная память, переменные или регистры.
Igor Korshunov

Topics: 6
Messages: 1531

My Profile
23.11.2017 15:59:49 Скоробогатько Степан

jmp	begin
a	db	-10
c	db	-20
x	dw	40
y	dw	-50
res	dw	0
begin:
mov ax,x
imul y
cmp ax,0
jl metk1
mov al,a
imul a
mov bx,ax
mov ax,x
cwd
idiv bx
mov res,ax
mov al,c
imul c
mov bx, ax
cwd
mov ax, y
cwd
idiv bx
add res, ax
mov ax,x
imul x
mov bx,ax
mov ax,y
imul y
imul bx
sub res,ax
jmp halt
metk1:
mov al,a
cbw
mov bx,ax
mov ax,x
imul ax
idiv bx
mov cx,ax
mov ax,y
imul y
idiv c
cbw
add cx,ax
mov al,c
imul a
sub cx,ax
neg cx
mov res,cx
jmp halt
halt:
jmp halt;E


23.11.2017 16:25:07 СкоробогатькоСтепан

jmp	begin
a	db	-10
c	db	-20
x	dw	40
y	dw	-50
res	dw	0
begin:
mov ax,x
imul y
cmp ax,0
jl metk1
mov al,a
imul a
mov bx,ax
mov ax,x
cwd
idiv bx
mov res,ax
mov al,c
imul c
mov bx, ax
cwd
mov ax, y
cwd
idiv bx
add res, ax
mov ax,x
imul x
mov bx,ax
mov ax,y
imul y
imul bx
sub res,ax
jmp halt
metk1:
mov al,a
cbw
mov bx,ax
mov ax,x
imul ax
idiv bx
mov cx,ax
mov al,c
cbw
mov bx,ax
mov ax,y
imul y
idiv bx
add cx,ax
mov al,c
imul a
sub cx,ax
mov ax, cx
mov bx,	-1
imul bx
sub res, ax
jmp halt
halt:
jmp halt;$E

 
Forum Index ->Учебный процесс ГГУ/СШ 27 ->Проектирование цифровых систем 1, 2, 3
Time:0,188