Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/4: Рейтинг темы: голосов - 4, средняя оценка - 4.50
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
1

Перемещение из массива

18.12.2013, 15:33. Просмотров 633. Ответов 12
Метки нет (Все метки)

Задание звучит так:
В 1-мерном массиве из 30 элементов выделить числа, имеющие четное количество разрядов и переместить их в структуру данных «запись».

В общем массив, сделал, даже отсортировал его, но вот как сделать остальное, как разрядность определить, и перенести в эту... "запись" - я не знаю. Подскажите, как должен код выглядеть, с учётом моего кода. Заранее благодарю!
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
.386
.model  flat, stdcall
option  casemap:none
include   c:\ollydbg\include\windows.inc
include   c:\ollydbg\include\user32.inc
include   c:\ollydbg\include\kernel32.inc
include   c:\ollydbg\include\fpu.inc
includelib  c:\ollydbg\lib\user32.lib
includelib  c:\ollydbg\lib\kernel32.lib
includelib  c:\ollydbg\lib\fpu.lib
 
BSIZE     equ  8
 
.data
    m dd 90,20,30,101,102,130,141,162,27,86,201,110,120,100,140,190,220,310,103,111,230,148,167,25,83,281,4108, 22,134,149
    stdout    dd  ?
    cWritten  dd  ?
    buf       db BSIZE dup (?)
    fmt   db "%d",13,10,0 
    fmt2   db "count=%d"
    count dd 0
    chng dd ?
.code
start:
    invoke  GetStdHandle, STD_OUTPUT_HANDLE
    mov stdout, eax
    
    mov edi, 0
    mov ecx, 0
.REPEAT
    push ecx
    mov eax,m[edi]
    invoke  wsprintf, ADDR buf, ADDR fmt,eax
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
    add edi,4
    pop ecx
    inc ecx
.UNTIL ecx == 15
     
    mov edi, 0
    mov esi, 0
.REPEAT
    mov esi, 56
    .WHILE esi>edi
        mov eax, m[esi]
        .IF eax<m[esi-4]
            mov chng, eax
            mov eax, m[esi-4]
            mov m[esi], eax
            mov eax, chng
            mov m[esi-4], eax
            inc count
        .ENDIF
        sub esi, 4
    .ENDW
    add edi,4
.UNTIL edi == 56
 
    mov edi, 0
    mov ecx, 0
.REPEAT
    push ecx
    mov eax,m[edi]
    invoke  wsprintf, ADDR buf, ADDR fmt,eax
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
    add edi,4
    pop ecx
    inc ecx
.UNTIL ecx == 15
           
    invoke  wsprintf, ADDR buf, ADDR fmt2,count
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
 
invoke  ExitProcess, 0
end start
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.12.2013, 15:33
Ответы с готовыми решениями:

Перемещение чисел из одного массива в другой
Привет знатоки ассемблера. В университете дали задачку: Есть массив с числами....

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

Перемещение элементов массива
Переместить однозначные числа в конец массива. При этом порядок следования...

Перемещение массива с PictureBox
Есть массив с PictureBox'ами, как осуществить их перемещение вверх, так чтобы...

Перемещение элементов массива
Дан массив размера n. Переместить первые его k (k&lt;=n) элементов в конец...

12
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
18.12.2013, 17:35 2
Кмк, примерно так:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
; ESI -> указывает на начало массива m
; EDI -> указывает на начало массива "запись", сами обзовёте.
        mov ecx, 30 ; размер массива
@l: lodsd       ; EAX = m[ESI++]
    push    ecx ; пока сохраняем
    push    eax
    mov cx, 32  ; бита
    xor ebx, ebx; счётчик битов-"единичек"
@@: rcl eax, 1  ; сдвигаем EAX влево, флаг CY = старшему биту EAX
    adc ebx, 0  ; прибавляем флаг CY к счётчику
    loop    @b  ; цикл на 32 бита
    pop eax
    bt  ebx, 0  ; проверяем на чётность, если нечётное, флаг CY = 1
    jc  @f  ; если кол-во битов-"единичек" нечётное, не сохраняем
    stosd           ; [EDI++] = EAX
@@: pop ecx
    loop    @l
0
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
18.12.2013, 19:22  [ТС] 3
спасибо, попробую. Я так понял, это отдельно вы написали код, не для вставки в мой?
0
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
18.12.2013, 19:41 4
Цитата Сообщение от Boba_Fet Посмотреть сообщение
не для вставки в мой?
Вставьте куда хотите. Я просто не любитель стиля написания с вызовами голого API, .REPEAT и прочих директив с точками.
0
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
18.12.2013, 19:46  [ТС] 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
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
93
94
95
96
97
98
99
.386
.model  flat, stdcall
option  casemap:none
include   d:\masm32\include\windows.inc
include   d:\masm32\include\user32.inc
include   d:\masm32\include\kernel32.inc
include   d:\masm32\include\fpu.inc
includelib  d:\masm32\lib\user32.lib
includelib  d:\masm32\lib\kernel32.lib
includelib  cd:\masm32\lib\fpu.lib
 
BSIZE     equ  8
 
.data
    m dd 90,20,30,101,102,130,141,162,27,86,201,110,120,100,140,190,220,310,103,111,230,148,167,25,83,281,4108, 22,134,149
    stdout    dd  ?
    cWritten  dd  ?
    buf       db BSIZE dup (?)
    fmt   db "%d",13,10,0 
    fmt2   db "count=%d"
    count dd 0
    chng dd ?
.code
start:
    invoke  GetStdHandle, STD_OUTPUT_HANDLE
    mov stdout, eax
    
    mov edi, 0
    mov ecx, 0
.REPEAT
    push ecx
    mov eax,m[edi]
    invoke  wsprintf, ADDR buf, ADDR fmt,eax
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
    add edi,4
    pop ecx
    inc ecx
.UNTIL ecx == 15
     
    mov edi, 0
    mov esi, 0
 
    ESI m
    EDI _m
 
        mov ecx, 30 ; размер массива
@l: lodsd       ; EAX = m[ESI++]
    push    ecx ; пока сохраняем
    push    eax
    mov cx, 32  ; бита
    xor ebx, ebx; счётчик битов-"единичек"
@@: rcl eax, 1  ; сдвигаем EAX влево, флаг CY = старшему биту EAX
    adc ebx, 0  ; прибавляем флаг CY к счётчику
    loop    @b  ; цикл на 32 бита
    pop eax
    bt  ebx, 0  ; проверяем на чётность, если нечётное, флаг CY = 1
    jc  @f  ; если кол-во битов-"единичек" нечётное, не сохраняем
    stosd           ; [EDI++] = EAX
@@: pop ecx
    loop    @l
 
 
.REPEAT
    mov esi, 56
    .WHILE esi>edi
        mov eax, m[esi]
        .IF eax<m[esi-4]
            mov chng, eax
            mov eax, m[esi-4]
            mov m[esi], eax
            mov eax, chng
            mov m[esi-4], eax
            inc count
        .ENDIF
        sub esi, 4
    .ENDW
    add edi,4
.UNTIL edi == 56
 
    mov edi, 0
    mov ecx, 0
.REPEAT
    push ecx
    mov eax,m[edi]
    invoke  wsprintf, ADDR buf, ADDR fmt,eax
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
    add edi,4
    pop ecx
    inc ecx
.UNTIL ecx == 15
           
    invoke  wsprintf, ADDR buf, ADDR fmt2,count
    invoke  WriteConsoleA, stdout, ADDR buf,\
    BSIZE, ADDR cWritten, NULL
 
invoke  ExitProcess, 0
end start
0
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
18.12.2013, 21:34 6
Вобщем, переписал всё, кроме сортировки - с ней разбирайтесь сами:
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
;include \masm32\include\user32.inc
;include \masm32\include\kernel32.inc
;include \masm32\include\fpu.inc
include \masm32\include\msvcrt.inc
 
includelib \masm32\lib\msvcrt.lib
;includelib \masm32\lib\user32.lib
;includelib \masm32\lib\kernel32.lib
;includelib \masm32\lib\fpu.lib
 
;BSIZE equ 8
 
.data
m   dd  90,20,30,101,102,130,141,162,27,86,201,110,120,100,140,190,220,310,103,111,230,148,167,25,83,281,4108, 22,134,149
m_sz    =       ($ - m)/4
_m  dd  m_sz dup(0)
;stdout dd ?
;cWritten dd ?
;buf db BSIZE dup (?)
fmt db '%d',13,10,0 
fmt2 db 'count=%d'
count dd 0
;chng dd ?
_msg    db  'Elements with even ',22h,'ones',22h,' bit count',0Dh,0Ah,0
.code
start:
;invoke GetStdHandle, STD_OUTPUT_HANDLE
;mov stdout, eax
 
;mov edi, 0
;mov ecx, 0
;.REPEAT
;push ecx
;mov eax,m[edi]
;invoke wsprintf, ADDR buf, ADDR fmt,eax
;invoke WriteConsoleA, stdout, ADDR buf,\
;BSIZE, ADDR cWritten, NULL
;add edi,4
;pop ecx
;inc ecx
;.UNTIL ecx == 15
    lea esi, m
    mov ecx, m_sz
@@: lodsd
    push    ecx
    invoke  crt_printf, ADDR fmt, eax
    pop ecx
    loop    @b
 
    lea esi, m
    lea     edi, _m
 
;ESI m
;EDI _m
    invoke  crt_puts, ADDR _msg
 
    mov ecx, m_sz; размер массива
@l:     lodsd       ; EAX = m[ESI++]
    push    ecx ; пока сохраняем
    push    eax
    mov     cx, 32  ; бита
    xor     ebx, ebx; счётчик битов-"единичек"
@@:     rcl eax, 1  ; сдвигаем EAX влево, флаг CY = старшему биту EAX
    adc     ebx, 0  ; прибавляем флаг CY к счётчику
    loop    @b  ; цикл на 32 бита
    pop     eax
    bt  ebx, 0  ; проверяем на чётность, если нечётное, флаг CY = 1
    jc  @f  ; если кол-во битов-"единичек" нечётное, не сохраняем
    stosd       ; [EDI++] = EAX
    invoke  crt_printf, ADDR fmt, eax
@@:     pop ecx
    loop    @l
 
 
.REPEAT
mov esi, 56
.WHILE esi>edi
mov eax, m[esi]
.IF eax<m[esi-4]
mov edx, eax
mov eax, m[esi-4]
mov m[esi], eax
mov eax, edx
mov m[esi-4], eax
inc [count]
.ENDIF
sub esi, 4
.ENDW
add edi,4
.UNTIL edi == 56
 
;mov edi, 0
;mov ecx, 0
;.REPEAT
    mov ecx, m_sz
    lea esi, m
@@: lodsd
    push    ecx
    invoke  crt_printf, ADDR fmt, eax
    pop ecx
    loop    @b
;mov eax,m[edi]
;invoke wsprintf, ADDR buf, ADDR fmt,eax
;invoke WriteConsoleA, stdout, ADDR buf,\
;BSIZE, ADDR cWritten, NULL
;add edi,4
;pop ecx
;inc ecx
;.UNTIL ecx == 15
 
    invoke  crt_printf, ADDR fmt2, [count]
;invoke wsprintf, ADDR buf, ADDR fmt2,count
;invoke WriteConsoleA, stdout, ADDR buf,\
;BSIZE, ADDR cWritten, NULL
    invoke  crt_exit, 0
;invoke ExitProcess, 0
    end start
1
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
18.12.2013, 22:43  [ТС] 7
Огромнейшее спасибо!!!

Добавлено через 16 минут
И если можно ещё 1 вопрос, а можно этот массив заполнить случайными числами?
Как я понимаю, я меняю
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
.data
m   dd  90,20,30,101,102,130,141,162,27,86,201,110,120,100,140,190,220,310,103,111,230,148,167,25,83,281,4108, 22,134,149
m_sz    =       ($ - m)/4
_m  dd  m_sz dup(0)
 
fmt db '%d',13,10,0 
fmt2 db 'count=%d'
count dd 0
 
_msg    db  'Elements with even ',22h,'ones',22h,' bit count',0Dh,0Ah,0
.code
start:
на
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
.data
m   dd  30(?)
m_sz    =       ($ - m)/4
_m  dd  m_sz dup(0)
 
fmt db '%d',13,10,0 
fmt2 db 'count=%d'
count dd 0
 
_msg    db  'Elements with even ',22h,'ones',22h,' bit count',0Dh,0Ah,0
.code
start:
верно? я просто ориентируюсь по примеру, на этом же форуме...
0
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
18.12.2013, 23:01 8
Цитата Сообщение от Boba_Fet Посмотреть сообщение
верно?
Да, но всё же стр. 3 и 4 лучше перетащить в хвост секции .data .
1
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
18.12.2013, 23:12  [ТС] 9
"syntax error in expression" - выводит эту ошибку на стр. 2, в чём дело? Разве это значение не показывает, максимальное кол-во элементов в массиве?
Assembler
1
2
3
4
5
6
7
8
9
10
11
.data
m   dd 30 (?)
 
fmt db '%d',13,10,0 
fmt2 db 'count=%d'
count dd 0
 
_msg    db  'Elements with even ',22h,'ones',22h,' bit count',0Dh,0Ah,0
m_sz    =       ($ - m)/4
_m  dd  m_sz dup(0)
.code
Добавлено через 2 минуты
И разве не нужно для заполнения рандомно вводить процедуру :WRandom ?
0
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
18.12.2013, 23:28 10
Цитата Сообщение от Boba_Fet Посмотреть сообщение
m dd 30 DUP(?)
Кое-что забыли...
1
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
18.12.2013, 23:38  [ТС] 11
Точно! Пропустил... Работает, отлично, правда есть одно но. Не может же быть, что эти первые 30 нулей он рандомно может придумать...
0
Миниатюры
Перемещение из массива  
Charles Kludge
Клюг
7645 / 3160 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
19.12.2013, 00:05 12
Тогда в начало вставьте
Assembler
1
2
    include \masm32\include\masm32.inc
    includelib \masm32\lib\masm32.lib
Ну начало кода будет выглядеть так:
Assembler
1
2
3
4
5
6
7
.code
start:
    mov ecx, m_sz
    lea edi, m
@@: invoke  nrandom, eax
    stosd
    loop    @b
0
Boba_Fet
1 / 1 / 1
Регистрация: 05.01.2013
Сообщений: 57
19.12.2013, 00:24  [ТС] 13
Вы уж извините, что возможно отнимаю ваше время, но я бы так не пёкся об этой работе на 200%, если бы это не была курсовая. Теперь при запуске вылетает ошибка, уже системная, о закрытие консоли.
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
                    .386
.model flat, stdcall
option casemap:none
include d:\masm32\include\windows.inc
include d:\masm32\include\user32.inc
include d:\masm32\include\kernel32.inc
include d:\masm32\include\fpu.inc
include d:\masm32\include\msvcrt.inc
include d:\masm32\include\masm32.inc
 
includelib d:\masm32\lib\msvcrt.lib
includelib d:\masm32\lib\user32.lib
includelib d:\masm32\lib\kernel32.lib
includelib d:\masm32\lib\fpu.lib
includelib d:\masm32\lib\masm32.lib
 
 
.data
m   dd 30 DUP(?)
 
 
fmt db '%d',13,10,0 
fmt2 db 'count=%d'
count dd 0
 
_msg    db  'Elements with even ',22h,'ones',22h,' bit count',0Dh,0Ah,0
m_sz    =       ($ - m)/4
_m  dd  m_sz dup(0)
.code
start:
 
    mov ecx, m_sz
    lea edi, m
@@: invoke  nrandom, eax
    stosd
    loop    @b
 
    lea esi, m
    lea     edi, _m
 
 
    invoke  crt_puts, ADDR _msg
 
    mov ecx, m_sz; ?????? ???????
@l:     lodsd       ; EAX = m[ESI++]
    push    ecx ; ???? ?????????
    push    eax
    mov     cx, 32  ; ????
    xor     ebx, ebx; ??????? ?????-"????????"
@@:     rcl eax, 1  ; ???????? EAX ?????, ???? CY = ???????? ???? EAX
    adc     ebx, 0  ; ?????????? ???? CY ? ????????
    loop    @b  ; ???? ?? 32 ????
    pop     eax
    bt  ebx, 0  ; ????????? ?? ????????, ???? ????????, ???? CY = 1
    jc  @f  ; ???? ???-?? ?????-"????????" ????????, ?? ?????????
    stosd       ; [EDI++] = EAX
    invoke  crt_printf, ADDR fmt, eax
@@:     pop ecx
    loop    @l
 
 
.REPEAT
        mov esi, 56
        .WHILE esi>edi
                mov eax, m[esi]
        .IF eax<m[esi-4]
                mov edx, eax
                mov eax, m[esi-4]
                mov m[esi], eax
                mov eax, edx
                mov m[esi-4], eax
                inc [count]
        .ENDIF
        sub esi, 4
        .ENDW
        add edi,4
.UNTIL edi == 56
 
 
    mov ecx, m_sz
    lea esi, m
@@: lodsd
    push    ecx
    invoke  crt_printf, ADDR fmt, eax
    pop ecx
    loop    @b
 
 
    invoke  crt_printf, ADDR fmt2, [count]
    invoke  crt_exit, 0
 
    end start
0
19.12.2013, 00:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2013, 00:24

Перемещение элементов массива
Здравствуйте, помогите пожалуйста с задачкой.. я написала, но не правильно мне...

Перемещение елемента массива
я создал двумерный массив и нарисовал ним текстовое поле примерно такое...

Перемещение элемента внутри массива
подскажите как сделать движение &quot;*&quot; по массиву без управления клавиотурой


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

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

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