Помощь - Поиск - Пользователи - Календарь
Полная версия: Помогите решить задачу с матрицей (ассемблер)
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ассемблер
1147
Объясните пожалуйста как можно выполнить следующее задание: Дана матрица 6х5. Вычеркнуть столбец с заданным номером.
мисс_граффити
На каком этапе выполнения возникают сложности?
Показывай, что уже сделал.


Вообще - по сути - надо удалить каждый n-ный элемент (т.е. сдвинуть все, что после него стоит).
1147
Я вообще не представляю как в компиляторе можно представить матрицу. Задания которые мне приходилось делать были на выполнение арифметических действий (с ассемблером я очень мало знаком)-это не трудно-результат видишь в определенном регистре. А тут нужно как-то сделать целую матрицу, да еще столбец вычеркнуть. Про матрицы я сейчас пытаюсь разобраться, но как вычеркнуть столбец мне вообще не ясно
мисс_граффити
(просьба не придираться - объясняю все упрощенно, упуская некоторые не значимые в данном случае нюансы)
Пишу в предположении, что ты правда хочешь разобраться, а не "лишь бы сдать".
Человеку удобно представлять матрицу в виде строк и столбцов:
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
большое спасибо мисс граффити!
1147
Задача такая:
Дана матрица 6х5. Вычеркнуть столбец с заданным номером
Lapp
Цитата(1147 @ 19.10.2008 14:25) *
Вычеркнуть столбец с заданным номером
Как организована память для матрицы? По строкам или по столбцам?
1147
по столбцам
Lapp
Цитата(1147 @ 20.10.2008 0:44) *
по столбцам
Ну, тогда все просто. Кусок памяти,начинающийся сразу за вычеркиваемым столбцом и содержащий весь остаток матрицы, двигаешь влево на длину столбца.
1147
мне непонятно только как и где задать номера столбцов матрицы чтобы я мог осуществить сдвиг с такого-то столбца влево
Lapp
Цитата(1147 @ 20.10.2008 11:49) *
как и где задать номера столбцов матрицы

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

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
Какой у тебя ассемблер, уточни...

Вот так должно отработать под 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
у меня Radasm
volvo
RadASM - это среда разработки... Она работает со многими компиляторами: и с MASM-ом и с TASM-ом, FASM и NASM тоже поддерживаются... Вот я и спрашиваю, чем именно из вышеперечисленного ты пользуешься?
1147
тогда Masm

Добавлено через 14 мин.
masm32 точнее
volvo
Ну, а 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
спасибо, попытаюсь разобраться...
Lapp
М
1147, почему надо было создавать две одинаковые темы?? Чтобы модераторы не скучали?..
Объединяю темы.
Руки чешутся закрыть, но боюсь, появится еще одна..




Добавлено через 3 мин.
Всем рекомендую посмотреть, как человек за 40 дней полностью забывает все и начинает по новой (переход от сообщения №5 к №6)
1147
допустим я вычислил номер элемента который нужно сдвинуть, но как осуществить непосредственно сдвиг чтобы в основной памяти один элемент матрицы стал на место другого?
volvo
Цитата
как осуществить непосредственно сдвиг чтобы в основной памяти один элемент матрицы стал на место другого?
В esi - адрес ячейки, откуда перемещать, в edi - адрес ячейки куда перемещать. В ecx - количество элементов для перемещения... И вызываешь REP MOVSB для байт, REP MOVSW для слов, или REP MOVSD для двойных слов...

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

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

Добавлено через 48 сек.
ESI и EDI
volvo
Цитата
как-то там слишком много всего написано. Мне в институте преподаватель сказал что это делается гораздо проще. С помощью двух циклов-внутренний по строкам, внешний по столбцам
С твоим преподавателем в принципе все понятно... "Легче", конечно, сделать 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
Жду более "легкого" решения...

как сделаю, обязательно выложу
Гость
Более легкое решение:


;Дана матрица 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
блин это не гость. Это я выложил более легкое решение как и обещал. забыл войти просто
volvo
Цитата
Это я выложил более легкое решение как и обещал
Угу... Настолько легкое, что компилировать его MASM 6.14 напрочь отказался... Хотя правильно. Оно же легкое, чтобы оно было работоспособным - это совсем не обязательно, об этом речи не шло...

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

Добавлено через 7 мин.
и в допиливании и исправлении "ошибок" она нисколько не нуждается, разве только с целью отправки письма Биллу Гейтсу
1147
кроме того программа написана в masm32, с использованием 32х разрядных регистров. Я бы сильно удивился если бы она правильно работала в masm 6.14
Гость
Нужно с клавиатуры ввести предложение а после заменить в предложении символ "а"(или другой), на символ "о"
Гость
[quote name='Гость' date='1.05.2013 15:29' post='162058']
Нужно с клавиатуры ввести предложение а после заменить в предложении символ "а"(или другой), на символ "о"
Желательно на 32 и 16 бит в TASMe
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.