Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
1

Почему срабатывает только одна итерация цикла

26.11.2012, 21:23. Просмотров 858. Ответов 11
Метки нет (Все метки)

Только начал изучать язык, и хотел бы разобраться с Loop ' ми. писал и так и эдак, гуглил тоже по разному, не могу реализовать его сам. Подскажите, почему цикл пробегается только 1 раз? Что не так я делаю?
Собственно хочу написать программу выделения подстроки(str4) из введенной (str1), с введенного номера, определенной длинны.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
.386
 
 
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
 
Asize equ 60
 
.data ;эта секция наиболее универсальная мы резервируем память под данные и сразу же объявляем их
msg1 db "Vvedite 1 stroky: ",0dh,0ah
msg2 db "Vvedite index nachala: ",0dh,0ah
msg3 db "Vvedite dlinnu: ",0dh,0ah
 
.data? ;в данной секции мы нельзя инициализировать переменные
 
str1 db 32 dup (' '),'$' ;Введенные символы
str2 db 32 dup (' '),'$' ;Введенные символы
str3 db 32 dup (' '),'$' ;Введенные символы
str4 db 32 dup (' '),'$' ;Введенные символы
 
stdin dd ? ;dd - 4 байта - 2 слова =8 символам
stdout dd ?
cRead dd ?
cWritten dd ?
res dd ?
.code
 
 
start:
invoke GetStdHandle,STD_OUTPUT_HANDLE ;Дескриптор стандартного устройства ввода данных.
;Вначале, это - дескриптор консольного буфера ввода
 
mov stdout,eax ;копирует значение переменной stdin в регистр eax
invoke GetStdHandle,STD_INPUT_HANDLE
mov stdin,eax;
 
invoke WriteConsoleA,stdout,ADDR msg1,SIZEOF msg1,ADDR cWritten,NULL
invoke ReadConsole,stdin,ADDR str1,Asize,ADDR cRead,NULL ;считываем 1 строку с консоли
 
invoke WriteConsoleA,stdout,ADDR msg2,SIZEOF msg2,ADDR cWritten,NULL
invoke ReadConsole,stdin,ADDR str2,Asize,ADDR cRead,NULL ;считываем 1 индекс с консоли
 
invoke WriteConsoleA,stdout,ADDR msg3,SIZEOF msg3,ADDR cWritten,NULL
invoke ReadConsole,stdin,ADDR str3,Asize,ADDR cRead,NULL ;считываем 1 индекс с консоли
;-----------------------------------процесс сравнения строк-----------------------------------
CLD ;направление вперед(с начала в конец)
 
 
mov ecx,4
cikl:
inc ESI
inc EDI
LEA ESI,ES:str1
LEA EDI,ES:str4
movsb
loop cikl
 
 
 
 
 
 
invoke WriteConsoleA,stdout,ADDR str4,SIZEOF str4,ADDR cWritten,NULL
 
 
 
end start
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.11.2012, 21:23
Ответы с готовыми решениями:

В цикле for происходит только одна итерация при наличии вложенного цикла
не подскажите, нужно перебрать варианты перемножения переменных, в php и python у меня подобные...

почему не срабатывает последняя итерация
подскажите почему не срабатывает и как исправить чтобы был вывод i=3 ? (нужен тип double) ...

Как сделать так, чтобы при каждом клике происходила одна итерация цикла?
Надо, чтобы при каждом нажатии на лейбл происходила итерация цикла: public void...

Почему не срабатывает изменение границы цикла, принятое внутри цикла?
Работает цикл for-Next V_Rod = UBound(Rod, 2) For j = 1 To V_Rod For k = 1 To...

Почему срабатывает только один декоратор?
Пример тестовый, чтоб разобраться в декораторах. При прохождении по коду в режиме отладки: - во...

11
_lucius_
388 / 176 / 2
Регистрация: 14.03.2012
Сообщений: 443
26.11.2012, 22:13 2
Цитата Сообщение от Neraving Посмотреть сообщение
Подскажите, почему цикл пробегается только 1 раз?
Потому что movsb также как и loop использует неявно регистр ecx.
0
Vadimych
635 / 478 / 12
Регистрация: 10.01.2011
Сообщений: 1,047
27.11.2012, 06:00 3
Цитата Сообщение от _lucius_ Посмотреть сообщение
movsb... использует неявно регистр ecx
Без префикса rep?

Assembler
1
2
3
4
5
6
mov ecx,4
LEA ESI,str1
LEA EDI,str4
cikl:
movsb
loop cikl
А лучше просто
Assembler
1
rep movsb
вместо цикла.
1
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
27.11.2012, 09:21  [ТС] 4
ммм, спасибо.
а вот как можно считать число? т.е. имееем конкретый байт ввода, прогоняем
Assembler
1
2
call crt__getch
invoke crt_putchar,eax
или
Assembler
1
2
3
4
BSIZE equ 32
.data
buf BYTE BSIZE dup(?)
invoke ReadConsole,stdin,ADDR buf,BSIZE,ADDR cRead,NULL ;
Но после этого циклы типа mov ecx,eax работают только один раз.
А mov ecx,[buf] не работет вовсе ссылаясь на разность размеров.
0
Vadimych
635 / 478 / 12
Регистрация: 10.01.2011
Сообщений: 1,047
27.11.2012, 10:30 5
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
.686
 
.model flat, stdcall
option casemap :none
 
include \masm32\include\msvcrt.inc 
includelib \masm32\lib\msvcrt.lib
 
 
.data
msg db "Введите строку",0dh,0ah,0
msg1 db "Введите индекс начала", 0dh,0ah,0
msg2 db 'Введите длину',0dh,0ah,0
lang db 'Russian',0
fmt db '%u',0
 
.data?
index dd ?
len dd ?
 
.code
 
start proc
local string[260]:byte
 
invoke setlocale,LC_ALL,offset lang
invoke printf,offset msg
 
lea esi,string
mov edi,esi
invoke gets,esi
 
invoke printf,offset msg1
invoke scanf,offset fmt,offset index
 
invoke printf,offset msg2
invoke scanf,offset fmt,offset len
 
add esi,index
dec esi
mov ecx,len
rep movsb
mov byte ptr [edi],0
 
invoke printf,addr string
 
invoke _getch
invoke _exit
 
start endp
end start
1
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
27.11.2012, 11:09  [ТС] 6
Vadimych, это же программа на фасме? я просто на масме пишу, но инерпретировать получилось. спасибо.
0
Vadimych
635 / 478 / 12
Регистрация: 10.01.2011
Сообщений: 1,047
27.11.2012, 11:28 7
Цитата Сообщение от Neraving Посмотреть сообщение
то же программа на фасме?
Нет. Чистый masm без всяких примесей.
0
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
27.11.2012, 20:31  [ТС] 8
Vadimych, а можешь немного объяснить код?
Assembler
1
2
3
lea esi,string
mov edi,esi
invoke gets,esi
Здесь реализован ввод строки через invoke gets,esi , в esi и в edi лежат адреса на эту строку?

Assembler
1
2
3
4
5
add esi,index
dec esi
mov ecx,len
rep movsb
mov byte ptr [edi],0
тут мы прыгаем по индексу в строке, после чего запускаем цикл на копирование. Что выполняет dec esi? как работает mov byte ptr [edi],0 ?

Спасибо за код, на его примере пытался реализовать такую задачу:
Вводим строку, вводим символ. нужно перевернуть строку, между первым и последним вхождениями этого символа, если их больше 2.
разбил для простоты на этапы. Сначала пытаюсь написать используя предыдущий код поиск количества вхождений символа, и индексы первого и последнего.
Но в этот раз через jmp.


Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
.386
 
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
include \masm32\macros\macros.asm
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
 
.data
msg db "String:",0dh,0ah,0
msg1 db "Value:", 0dh,0ah,0
msg2 db 'Length',0dh,0ah,0
fmt db '%u',0
 
.data?
value dd ?
indexfirst ?
indexlast ?
 
.code
 
start proc
local string[20]:byte
local cont[2]:byte
 
 
invoke crt_printf,offset msg
lea esi,string
 
mov edi,esi
invoke crt_gets,esi
 
invoke crt_printf,offset msg1
invoke crt_scanf,offset fmt,offset value
 
mov cont,0
invoke crt_printf,addr cont
mov ecx,SIZEOF string
find:
LEA EAX,string
 
cmp value,EAX
JNE noinc
JE incr
 
noinc:
inc ecx
jmp find
 
incr:
inc cont
mov indexfirst, ecx
inc ecx
jmp find
 
add esi,index
dec esi
mov ecx,crt_len
rep movsb
mov byte ptr [edi],0
 
invoke crt_printf,addr value
 
invoke crt__getch
invoke crt__exit
 
start endp
end start
Компиляция проходит (ну раньше проходила до парочки исправлений), но cmd'шка зависала в процессе.
0
Vadimych
635 / 478 / 12
Регистрация: 10.01.2011
Сообщений: 1,047
27.11.2012, 20:38 9
Цитата Сообщение от Neraving Посмотреть сообщение
в esi и в edi лежат адреса
Да, совершенно верно. esi уменьшаем на 1 потому, что нумерация символов в строке начинается с нуля. Ноль записываем в конец строки после копирования для правильной работы printf, т.к. выводимая строка должна им заканчиваться.
1
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
27.11.2012, 20:49  [ТС] 10
Vadimych, мм, понятно в целом.
А как можно вывести содержание регистра/введенной переменно на экран?
invoke crt_printf,eax не получится же?

Если не сложно, подскажи плиз с моим кодом.
0
Vadimych
635 / 478 / 12
Регистрация: 10.01.2011
Сообщений: 1,047
27.11.2012, 21:54 11
Neraving, получите длину введённой строки с помощью функции strlen. Введите символ с помощью функции getchar. Сканируйте строку до первого совпадения. Затем, если надо перевернуть часть строки между первым и последним символами, равными введённому, сканируйте строку с конца назад. Если индексы не равны - переворачивайте и выводите на экран. Так приблизительно.

Добавлено через 18 минут
Не стесняйтесь пользоваться отладчиком. Вставляйте в код отладочные прерывания int 3 в проблемных местах. Анализируйте ошибки.
P.S. И не забывайте публикуя чужой код ссылаться на источник.
1
Neraving
0 / 0 / 0
Регистрация: 26.11.2012
Сообщений: 10
27.11.2012, 22:12  [ТС] 12
Vadimych, ммм, да, лучше попробую реализовать ваш способ.
а прерывания, насколько я знаю, в масме через вижуал студио не работают.
P.s. учту и постараюсь не забыть.
0
27.11.2012, 22:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2012, 22:12

Почему функция срабатывает только 1 раз
Тесть после 5 сек выводится google но через следующие 5 сек почемуто google так и остается а должно...

Почему выводится только одна строка?
Добрый вечер. Имеется длинная функция create or replace FUNCTION get_week_list2(i_code IN...

Почему выводится только одна запись из бд?
Вроде ж все нормально. Почему не выводит все. Не пойму :( while($myrow =...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru