║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
1

Зацикливается, причем весьма интересным способом.

30.03.2011, 23:55. Показов 2164. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Задание:
"Записати у нову стрічку кожен 3-й символ із стрічки довжиною «M» з позиції «P»"
"Записать в новую строку каждый 3-й символ со строки длиной «M» начиная с позиции «P»"
P = 12, M = 112

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

Еще есть вопрос: правильно ли я описал строки на 120 символов: strFrom и strTo
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
data segment
    ; add your data here!
    pkey    db  10, 13, 'press any key...$'
    str     db  '12345678901Hello world', 10, 13, '$'
    strFrom db  120     dup('aaabbbcccddd')
    strTo   db  120     dup('$')
    P       dw  12
    M       dw  112
ends
 
stack segment
    dw   128  dup(0)
ends
 
code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
 
    ; add your code here
    mov     AX, M
    sub     AX, P
    mov     BX, 3
    div     BX
    inc     AL
    cbw             ; ax = (M-P) / 3 + 1
    
    push    offset strFrom      ; destination
    mov     bx, P
    dec     bx
    add     bx, offset strTo    ; source
    push    bx                       
    push    ax                  ; number of iterations
                                  
    call    CopyFunction
    
    call    PressEnyKey
              
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends           
 
CopyFunction PROC
                        
    pop     cx          ; get number of iterations    
    
    CopyFunctionLoop:   
        pop     si      ; source
        lodsb
 
        add     si, 2   ; go to third element in source
        mov     bx, si
        
        pop     si      ; destination        
        stosb
        push    si      ; go to second element in destination
        push    bx
    loop CopyFunctionLoop  
     
    pop     si          ; normalization of destination
    pop     si
    mov     al, 10
    stosb     
    mov     al, 13
    stosb
    
    lea     dx, strTo   ; write strTo
    mov     ah, 9
    int     21h
    
    ret                 ; exit CopyFunction
    
CopyFunction ENDP     
 
PressEnyKey PROC
               
    ; write "press any key..."
    lea     dx, pkey
    mov     ah, 09h
    int     21h       
    
    ; wait any key
    mov     ah, 01h
    int     21h
    
    ret
    
PressEnyKey ENDP
                    
end start ; set entry point and stop the assembler.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.03.2011, 23:55
Ответы с готовыми решениями:

Не могу войти в биос никаким известным мне способом способом!
Ноут Acer 5V-531g.Перепробовал все что только можно.Ни одна комбинация не заходит в биос.По...

Игры с интересным сюжетом
Привет ребята. Подскажите пожалуйста игрушку с интересным сюжетом и нормальной графикой. Что-то на...

Создать спойлер с интересным условием
Приветствую, есть задача составить спойлер - разворачивающийся блок как например использует...

Продажа купонов Google AdWords по интересным ценам
<b>Продам купоны AdWords</b> для любых новых аккаунтов (14 дней), автоматическая конвертация в...

12
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
31.03.2011, 12:30 2
outoftime, когда срабатывает команда CALL в стек отправляется адрес команды находящейся за командой CALL чтобы на нее было передано управление после выхода из процедуры, это делает команда RET. У тебя
Assembler
1
2
3
push    bx                       
    push    ax                  ; number of iterations                                  
    call    CopyFunction
перед вызовом CopyFunction в стек отправляется два параметра
Assembler
1
2
3
CopyFunction PROC                        
    pop     cx ; здесь в СХ передается не number of iterations, а адрес возврата из процедуры    
CopyFunctionLoop:  pop     si; а здесь в SI отправляется number of iterations
а возврата из процедуры CopyFunction потерян, здесь два механизма передачи параметров, первый через стек и далее через обращение к ВР
Assembler
1
2
3
4
5
6
7
CopyFunction PROC
push bp; сохраняем значение BP
mov bp,sp 
теперь в [bp+0] старое значение ВР
в [bp+2] адрес возврата из CopyFunction
в [bp+4] number of iterations
в [bp+6] значение source
второй через регистры ведь при входе в CopyFunction в АХ number of iterations а в ВХ значение source
1
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
31.03.2011, 19:23  [ТС] 3
Mikl___, я знал что можно использовать регистры, ну а вдруг мне надо будет потом их спользовать, ладно загнул, просто у меня привычка, если начал что-то рыть то рою даже если это безсмысленно, так просто веселей изучать новый метериал.

Вопрос: вместо bp можно использовать bx? Насколько я понял при входе в процедуру мне нужно поставить ссылку на верх стека в bp (bx) а потом доставать значения, так как вверху у меня будет точка возврата функции, то доставать в том же порядке начиная со второго элемента, верно? (ладно, надо будет теорию почитать, а то забыл какой регистр отвечает за адрес стека, на сколько я понял это sp, на почве этого еще вопрос-догадка: что-бы попасть к элементу под верхним элементом стека, нужно прибавлять здвиг, верно?)

Если это все верно, тогда можно не использовать bp (bx) вовсе
Assembler
1
2
3
4
mov cx, [sp+2] ; counter
mov si, [sp+4] ; source
...
mov si, [sp+6] ; destination
Добавлено через 18 минут
Стек містить адреси повернення в операційну систему як для програми, так і для повернення підпрограм в головну програму. Регістр сегмента стека (SS) адресує даний сегмент.
Регістр ESP. Вказівник стеку забезпечує використання стека в пам'яті, дозволяє тимчасово зберігати адреси і дані. Цей регістр пов'язаний з регістром SP для адресації стека.
Регістр EBP. Вказівник бази полегшує доступ до параметрів: даних і адрес переданих через стек.
Это все что у меня есть по стеку, на данный момент я немного не пойму 2 момента:
1. если есть сегментный регистр, который указывает адрес стека - ss, тогда зачем еще 1 регистр - sp
2. допустим они есть, значит между ними есть разница, вопрос какая, а именно: как это сказывается на доступе к данным стека, уточняю, если брать адрес относительно ss тогда какой сдвиг нужен для доступа к 3-му байту стека?

Добавлено через 2 часа 9 минут
Со стеком так до конца не разобрался, но функцию все-таки нормально дописал.
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
76
77
78
79
80
81
82
83
84
85
data segment
    ; add your data here!
    pkey    db  'press any key...$'
    string  db  '12345678901Hello world', 10, 13, '$'
    strFrom db  117     dup('abcabccba')
    strTo   db  114     dup(0)
    P       dw  12
    M       dw  112
ends
 
stack segment
    dw   128  dup(0)
ends
 
code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
 
    ; add your code here
 
    mov     ax, M
    sub     bx, P
    mov     bl, 3
    div     bl
    inc     al
    cbw             
    ; number of iterations
    mov     cx, ax  ; CX = (M-P) / 3 + 1
    
    lea     si, strFrom         ; source
    add     si, P
    dec     si
    lea     di, strTo           ; destination
    
    call    CopyFunction
    
    call    PressEnyKey
              
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends           
 
CopyFunction PROC
 
    cld
    CopyFunctionLoop:   
        lodsb
        add     si, 2       ; go to third element in source
        stosb               ; copy to destination
    loop CopyFunctionLoop  
     
    mov     al, 10
    stosb
    mov     al, 13
    stosb
    mov     al, '$'
    stosb
    
    lea     dx, strTo   ; write strTo
    mov     ah, 09h
    int     21h
    
    ret                 ; exit CopyFunction
    
CopyFunction ENDP     
 
PressEnyKey PROC
               
    ; write "press any key..."
    lea     dx, pkey
    mov     ah, 09h
    int     21h       
    
    ; wait any key
    mov     ah, 01h
    int     21h
    
    ret
    
PressEnyKey ENDP
 
end start ; set entry point and stop the assembler.
0
4174 / 1824 / 218
Регистрация: 06.10.2010
Сообщений: 4,111
31.03.2011, 20:45 4
если есть сегментный регистр, который указывает адрес стека - ss, тогда зачем еще 1 регистр - sp
Физический адрес вычисляется по формуле ss*16+sp, что позволяет адресовать 1088 Кб памяти.
Если это все верно, тогда можно не использовать bp (bx) вовсе
Через sp нельзя обращаться к стеку - не предусмотрено архитектурой. А вот через esp - можно.
1
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
01.04.2011, 05:31 5
Цитата Сообщение от outoftime
Вопрос: вместо bp можно использовать bx?
Можно, но использование адресации через ВР по умолчанию предполагает обращение к сегменту стека, а использование ВХ, SI и DI по умолчанию предполагает обращение к сегменту данных. Поэтому при передаче в стек аргументов и последующему обращению через ВХ, SI и DI нужно делать так
mov ax,ss:[bx+10] а в случае с использованием ВР только mov ax,[bp+10]
1
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
02.04.2011, 10:51  [ТС] 6
Цитата Сообщение от Mikl___ Посмотреть сообщение
использование ВХ, SI и DI по умолчанию предполагает обращение к сегменту данных
т.е. пара будет
Assembler
1
2
mov ax, ds:[bx+10] ; default
mov ax, ss:[bx+10] ; reading from stack
Спасибо за ответ.
0
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
04.04.2011, 03:54 7
outoftime, по дефаулту будет
mov ax,[bx+10] = mov ax,ds:[bx+10]
и mov ax,[bp+10] = mov ax, ss:[bp+10]
1
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
04.04.2011, 10:01  [ТС] 8
Mikl___, т.е. явно привязывать сдвиг относительно определенного сегментного регистра нельзя, верно?
Assembler
1
mov ax,ss:[bx+10] ; epic fail
0
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
04.04.2011, 10:10 9
outoftime, там нет сдвига, просто команда с явным определением сегмента ss: оказывается на 1 байт длиннее чем без такого определения
Assembler
1
2
3
кодировка |       команда      | длина в байтах
368B4710h | mov ax,ss:[bx+10h] | 4 байта
8B4610h   | mov ax,[bp+10h]    | 3 байта
Да и выполняться такая команда будет дольше, так как фактически это две команды, а не одна 36h = SS: / 8B4710h = mov ax,[bx+10h]
1
║XLR8║
1212 / 909 / 270
Регистрация: 25.07.2009
Сообщений: 4,361
Записей в блоге: 5
04.04.2011, 10:19  [ТС] 10
Mikl___,
Цитата Сообщение от Mikl___ Посмотреть сообщение
там нет сдвига
Я то думал, что адрес указанный таким видом:
Assembler
1
mov ax,[bp+0AH]
это адрес смещенный на bp+10 относительно ss, куда-бы он не указывал.
0
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
04.04.2011, 10:21 11
А выполнять команды типа mov ax,ss:[bx+10h] тебе никто не может запретить, тем и хорош ассемблер -- никаких ограничений ! Но предупредить тебя все-таки мы должны
здесь ты прав - адрес смещенный на bp+10 относительно ss
полный адрес = SS*16 + BP + 10 -- наверное, это трудности перевода с украинского на русский
1
outoftime
04.04.2011, 10:26  [ТС]
  #12

Не по теме:

Mikl___, аж обидно, сам украинец, живу в Украине, а русский и английский знаю, порой, лучше родного... ппц

0
Ушел с форума
Автор FAQ
16332 / 7653 / 1072
Регистрация: 11.11.2010
Сообщений: 13,676
04.04.2011, 10:29 13
не по теме
outoftime, не расстраивайся, я могу на украинский только с Гуглом переводить
0
04.04.2011, 10:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.04.2011, 10:29
Помогаю со студенческими работами здесь

Ищу идеи (C#, Technology), чем-бы *интересным* заняться?
Посоветуйте, какими коммерческими проектами я мог бы заниматься, с учетом таких особенностей: ...

Дополнить игру лабиринт чем-нибудь интересным
Помогите дополнить лабиринт чем-нибудь интересным) в Pascal uses crt; const KEY_LEFT = 37;...

Весьма серьезный Winlocker
Доброе время суток. Задача такая: на компе появился Winlocker. Выглядит так: окно с обычными...

Поделитесь интересным опытом по игре в Rome Total War
Что вы ожидаете по поводу выхода в свет самой ожидаемой игры из серии Total War: 2-ой части Rome...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru