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

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

Форум «Всё о Паскале» _ Assembler _ Помогите решить задачу с матрицей (ассемблер)

Автор: 1147 8.09.2008 16:39

Объясните пожалуйста как можно выполнить следующее задание: Дана матрица 6х5. Вычеркнуть столбец с заданным номером.

Автор: мисс_граффити 8.09.2008 16:52

На каком этапе выполнения возникают сложности?
Показывай, что уже сделал.


Вообще - по сути - надо удалить каждый n-ный элемент (т.е. сдвинуть все, что после него стоит).

Автор: 1147 8.09.2008 17:09

Я вообще не представляю как в компиляторе можно представить матрицу. Задания которые мне приходилось делать были на выполнение арифметических действий (с ассемблером я очень мало знаком)-это не трудно-результат видишь в определенном регистре. А тут нужно как-то сделать целую матрицу, да еще столбец вычеркнуть. Про матрицы я сейчас пытаюсь разобраться, но как вычеркнуть столбец мне вообще не ясно

Автор: мисс_граффити 8.09.2008 21:19

(просьба не придираться - объясняю все упрощенно, упуская некоторые не значимые в данном случае нюансы)
Пишу в предположении, что ты правда хочешь разобраться, а не "лишь бы сдать".
Человеку удобно представлять матрицу в виде строк и столбцов:
1 2 3
4 5 6
7 8 9
компьютеру так неудобно. он будет хранить данные как
1 2 3 4 5 6 7 8 9
а где-то отдельно - информацию о том, как эти данные трактовать (что это 3*3, а не 9*1 или 1*9).

То есть задача сводится к удалению каждого 3-го элемента:
1 2 x 4 5 x 7 8 x
Теперь - матрицы применительно к ассемблеру (еще раз повторюсь - ему все равно, одномерный массив или двумерный! это - понятия из языков выского уровня).

вот небольшой пример работы с массивом:

;нахождение суммы нечетных элементов массива
.model small
.stack 512
.data
mas db 10 dup (31, 11, 26, 10, 8, 48, 21, 16, 65, 28)
sum dw 0
.code
;заносим адрес сегмента данных в DX
mov AX, @data
mov DS, AX
mov AX,0

;заносим адрес массива в BX
mov BX, offset mas
;в SI будем хранить номер элемента
mov SI,0
start:
;если дошли до последнего элемента
cmp SI,10
;переходим на метку finish
je finish

;заносим в AL элемент массива с номером SI
mov AL,[BX][SI]

;если число четное - переходим к метке cont
test AL,00000001b
jz cont
;иначе - прибавляем число к сумме
add AX,sum
mov sum,AX
cont:
;увеличиваем значение счетчика
inc SI
jmp start

finish:
mov ax,4c00h
int 21h
end

попробуй для начала разобраться в этом.
Возникнут вопросы - пиши...

Автор: 1147 9.09.2008 9:31

большое спасибо мисс граффити!

Автор: 1147 19.10.2008 14:25

Задача такая:
Дана матрица 6х5. Вычеркнуть столбец с заданным номером

Автор: Lapp 19.10.2008 18:55

Цитата(1147 @ 19.10.2008 14:25) *
Вычеркнуть столбец с заданным номером
Как организована память для матрицы? По строкам или по столбцам?

Автор: 1147 20.10.2008 0:44

по столбцам

Автор: Lapp 20.10.2008 2:50

Цитата(1147 @ 20.10.2008 0:44) *
по столбцам
Ну, тогда все просто. Кусок памяти,начинающийся сразу за вычеркиваемым столбцом и содержащий весь остаток матрицы, двигаешь влево на длину столбца.

Автор: 1147 20.10.2008 11:49

мне непонятно только как и где задать номера столбцов матрицы чтобы я мог осуществить сдвиг с такого-то столбца влево

Автор: Lapp 21.10.2008 0:09

Цитата(1147 @ 20.10.2008 11:49) *
как и где задать номера столбцов матрицы

Их не надо нигде как-то специально задавать. Просто вычисляешь по ним адрес. Например, адрес начального элемента i-того столбца будет:
ci = a + i*lc ,
где
ci - адрес начало i-того столбца,
a - адрес начала матрицы,
lc - длина столбца.
Это при условии, что числа однобайтовые, и нумерация идет с нуля.

Автор: 1147 21.10.2008 21:46

вот у меня кое-что получилось, но неправильно... в методичках насчет операции вычеркивания ничего нет. Делал по образцу примера по обработке массива

Start:
mov DI,0
mov ECX,2; номер вычеркиваемого столбца

cycle1:
push ECX
mov ECX,5
mov ECX,6
mov EBX,0
cycle2:
Mov AL, A+1[EBX]
MOV A[EBX],AL
ADD EBX,5
loop cycle2
pop ECX
loop cycle1

Автор: volvo 24.10.2008 14:31

Какой у тебя ассемблер, уточни...

Вот так должно отработать под TASM-ом (ты сказал, что у тебя матрица организована "по столбцам"):


; ...

.data
mx db 1, 2, 3, 4, 5 ; 1-ый стоблец
db 21, 22, 23, 24, 25 ; 2-ой столбец
db 31, 32, 33, 34, 35
db 41, 42, 43, 44, 45
db 51, 52, 53, 54, 55

rows dw 5 ; число столбцов
cols dw 5 ; число элементов в каждом столбце

to_delete equ 4 ; номер столбца для удаления

.code

; ну, тут разные процедуры, в частности - PrintMatrix для проверки

start:
mov ax, @data
mov ds, ax ; не забываем установить сегментные регистры !!!

push ds
pop es ; установка ES понадобится при использовании REP MOVSB

lea di, mx
call PrintMatrix ; печатаем начальную матрицу


mov ax, rows
sub ax, to_delete
mul cols
mov cx, ax ; счетчик повторений для REP MOVSB

cld ; проход слева направо
mov ax, to_delete
dec ax
mul cols

lea di, mx ; начало матрицы
add di, ax ; "приемник" для REP MOVSB

mov si, di
add si, cols ; "источник"для REP MOVSB

rep movsb ; ds:[si] -> es:[di]
dec rows ; уменьшаем число столбцов

lea di, mx
call PrintMatrix ; печатаем полученную матрицу

; все, можно выходить
mov ax, 4C00h
int 21h

end start


Автор: 1147 25.10.2008 19:15

у меня Radasm

Автор: volvo 25.10.2008 20:57

RadASM - это среда разработки... Она работает со многими компиляторами: и с MASM-ом и с TASM-ом, FASM и NASM тоже поддерживаются... Вот я и спрашиваю, чем именно из вышеперечисленного ты пользуешься?

Автор: 1147 25.10.2008 22:12

тогда Masm

Добавлено через 14 мин.
masm32 точнее

Автор: volvo 26.10.2008 12:04

Ну, а MASM - это вообще отдельный разговор. Тут все еще проще:

.486
.model flat, stdcall
option casemap :none

include F:\masm32\include\windows.inc ; always first
include F:\masm32\macros\macros.asm ; MASM support macros

; -----------------------------------------------------------------
; include files that have MASM format prototypes for function calls
; -----------------------------------------------------------------
include F:\masm32\include\masm32.inc
include F:\masm32\include\gdi32.inc
include F:\masm32\include\user32.inc
include F:\masm32\include\kernel32.inc

; ------------------------------------------------
; Library files that have definitions for function
; exports and tested reliable prebuilt code.
; ------------------------------------------------
includelib F:\masm32\lib\masm32.lib
includelib F:\masm32\lib\gdi32.lib
includelib F:\masm32\lib\user32.lib
includelib F:\masm32\lib\kernel32.lib

.data
mx dword 1, 2, 3, 4, 5
dword 21, 22, 23, 24, 25
dword 31, 32, 33, 34, 35
dword 41, 42, 43, 44, 45
dword 51, 52, 53, 54, 55

rows dword 5
cols dword 5
to_delete equ 4

.code

start:
call main
exit

main proc

call PrintTable
print chr$(13, 10)

mov eax, rows
sub eax, to_delete
mul cols
mov ecx, eax

cld
mov eax, (to_delete-1)*sizeof(dword)
mul cols

mov edi, offset mx
add edi, eax

mov esi, edi
mov eax, sizeof(dword)
mul cols
add esi, eax
rep movsd

dec rows
call PrintTable

Ret
main EndP

PrintTable proc

mov esi, offset mx

mov ebx, cols
mov edx, rows

mov edx, rows
.while edx > 0
push edx
print chr$(13, 10)
pop edx

mov ecx, ebx
.while ecx > 0
mov eax, [esi]
push ebx
push ecx
push edx
print str$(eax)
print chr$(' ')
pop edx
pop ecx
pop ebx
add esi, sizeof(dword)
dec ecx
.endw
dec edx
.endw

Ret
PrintTable EndP
end start


Автор: 1147 27.10.2008 11:08

спасибо, попытаюсь разобраться...

Автор: Lapp 30.10.2008 3:51

М
1147, почему надо было создавать две одинаковые темы?? Чтобы модераторы не скучали?..
Объединяю темы.
Руки чешутся закрыть, но боюсь, появится еще одна..




Добавлено через 3 мин.
Всем рекомендую посмотреть, как человек за 40 дней полностью забывает все и начинает по новой (переход от сообщения №5 к №6)

Автор: 1147 2.11.2008 18:12

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

Автор: volvo 2.11.2008 18:34

Цитата
как осуществить непосредственно сдвиг чтобы в основной памяти один элемент матрицы стал на место другого?
В esi - адрес ячейки, откуда перемещать, в edi - адрес ячейки куда перемещать. В ecx - количество элементов для перемещения... И вызываешь REP MOVSB для байт, REP MOVSW для слов, или REP MOVSD для двойных слов...

Я ж тебе привел пример, как это делается... Ты его смотрел вообще?

Автор: 1147 2.11.2008 19:05

смотрел разумеется. Но как-то там слишком много всего написано. Мне в институте преподаватель сказал что это делается гораздо проще. С помощью двух циклов-внутренний по строкам, внешний по столбцам

Добавлено через 10 мин.
Вот к примеру, самы простой вариант. Дан одномерный массив: 1,3,2,4,7,3. нужно удалить цифру 2 (тоесть сдвинуть 4,7,3 влево). какие адреса нужно указывать в ES и EDI?

Добавлено через 48 сек.
ESI и EDI

Автор: volvo 2.11.2008 20:29

Цитата
как-то там слишком много всего написано. Мне в институте преподаватель сказал что это делается гораздо проще. С помощью двух циклов-внутренний по строкам, внешний по столбцам
С твоим преподавателем в принципе все понятно... "Легче", конечно, сделать 2 цикла, вместо того одного, который сейчас у меня... А на MASM32 он что, распечатать матрицу (именно для этого используются у меня еще 2 цикла) может одним вызовом? Флаг ему в руки, пусть вызывает... Больше не получишь полных решений, буду приводить только тот кусок, который реализует задание... Вот:

Цитата

	mov eax, rows
sub eax, to_delete
mul cols
mov ecx, eax

cld
mov eax, (to_delete-1)*sizeof(dword)
mul cols

mov edi, offset mx
add edi, eax

mov esi, edi
mov eax, sizeof(dword)
mul cols
add esi, eax
rep movsd ; Один единственный цикл, больше никаких циклов нигде нет...

Все остальное к заданию напрямую не относится... Жду более "легкого" решения...

Цитата
Дан одномерный массив: 1,3,2,4,7,3. нужно удалить цифру 2 (тоесть сдвинуть 4,7,3 влево). какие адреса нужно указывать в ES и EDI?
Какое ЭТО имеет отношение к теме? Это не удаление столбца в матрице, записанной ПО СТОЛБЦАМ. Это удаление столбца в матрице, записанной ПО СТРОКАМ. Разницу замечаешь? Надо было говорить сразу, что тебе нужно... Тем более, тебя еще и переспросили...
В ESI - адрес "четверки", в EDI - адрес "двойки". Типы данных ты не привел, поэтому смещения от начала массива высчитывай сам... Удачи...

Автор: 1147 2.11.2008 21:35

Жду более "легкого" решения...

как сделаю, обязательно выложу

Автор: Гость 18.11.2008 12:41

Более легкое решение:


;Дана матрица 6х5. Вычеркнуть столбец с заданным номером.

.DATA
A dw 1,3,7,2,4
dw 9,1,3,5,6
dw 2,9,7,4,1
dw 8,2,5,3,7
dw 6,2,7,4,3
dw 5,9,3,5,1
.DATA?
inbuf DB 100 DUP (?)

.CODE

Start:

mov ecx,4; здесь задаем номер вычеркиваемого столбца (от 1 до 5)
mov edi,ecx
cycl0:
inc edi
loop cycl0
mov ebx,0
mov ax,A
mov ecx,4

cycl:
mov ax, A[bx+di]
mov A[bx+di]-2,ax
add di,2
loop cycl

mov ecx,4

cycl1:
mov ax, A[bx+di]+2
mov A[bx+di]-2,ax
add di,2
loop cycl1

mov ecx,4

cycl2:
mov ax, A[bx+di]+4
mov A[bx+di]-2,ax
add di,2
loop cycl2

mov ecx,4

cycl3:
mov ax, A[bx+di]+6
mov A[bx+di]-2,ax
add di,2
loop cycl3

mov ecx,4

cycl4:
mov ax, A[bx+di]+8
mov A[bx+di]-2,ax
add di,2
loop cycl4

mov ecx,4

cycl5:
mov ax, A[bx+di]+10
mov A[bx+di]-2,ax
add di,2
loop cycl5

mov ecx,6

cycl6:
mov ax, A[bx+di]+12
mov A[bx+di]-2,ax
add di,2
loop cycl6

Автор: 1147 18.11.2008 12:43

блин это не гость. Это я выложил более легкое решение как и обещал. забыл войти просто

Автор: volvo 18.11.2008 15:46

Цитата
Это я выложил более легкое решение как и обещал
Угу... Настолько легкое, что компилировать его MASM 6.14 напрочь отказался... Хотя правильно. Оно же легкое, чтобы оно было работоспособным - это совсем не обязательно, об этом речи не шло...

А после "допиливания" твоей "программы" dry.gif (почему ту программу, которая приведена в 17-ом посте не надо ни дорабатывать, ни исправлять ошибки, ничего, можно сразу проверить, а твою - нельзя?) она компилируется, но при запуске хочет сразу отправить письмо Биллу Гейтсу. Это ее основная функциональность?

Автор: 1147 19.11.2008 17:27

ее основная функциональность-удалять заданный столбец. У меня она работает без малейших ошибок. Более того, вчера в институте у меня ее приняли и защитали. Единственный недостаток-много лишних циклов. Ее можно было свести к 2м циклам, как я и говорил раньше. Тогда было бы еще проще

Добавлено через 7 мин.
и в допиливании и исправлении "ошибок" она нисколько не нуждается, разве только с целью отправки письма Биллу Гейтсу

Автор: 1147 19.11.2008 17:55

кроме того программа написана в masm32, с использованием 32х разрядных регистров. Я бы сильно удивился если бы она правильно работала в masm 6.14

Автор: Гость 1.05.2013 15:29

Нужно с клавиатуры ввести предложение а после заменить в предложении символ "а"(или другой), на символ "о"

Автор: Гость 1.05.2013 15:31

[quote name='Гость' date='1.05.2013 15:29' post='162058']
Нужно с клавиатуры ввести предложение а после заменить в предложении символ "а"(или другой), на символ "о"
Желательно на 32 и 16 бит в TASMe