Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для начинающих > [MASM] арифметика элементов масcивов


Автор: dimas_sceen 18.6.2009, 17:59
Здравствуйте!
Помогите решить задачу. Заданы два массива А и В по 20 элементов. Создать массив  С,  элемент  С[i]  которого  равен А[i]-B[i] при A[i]>B[i] и B[i]-A[i] при A[i]<B[i]. Это должна быть функция на ассемблере, которая будет вызивытся с программы на С++.

Код

extern void pr(int ,int *,int *,int *);
.....
//M-розмерность масивов
pr(M,A,B,C);


и код на ассемблере

Код

cseg segment PARA 'CODE'
  Assume cs:cseg
;==========================
_pr proc far
 push bp
mov bp,sp 
    push ds
    pusha

    mov si,[bp+6]
    mov cx,[si]
    mov si,[bp+8]
    mov ax,[bp+10]
    mov ds,ax
    mov di,[bp+12]
    mov bx,[bp+16]
    xor ax,ax
    mov dx,ax
m1: mov ax,[si]
    mov dx,[di]
    cmp ax,dx
    jnl m2
    sub dx,ax
    mov [bx],dx
    jmp m3
m2: sub ax,dx
    mov [bx],ax
m3: add bx,2
    add si,2
    add di,2
    loop m1
    popa
    pop ds
    pop bp
    retf
_pr endp
 cseg ends
end




Сейчас врезультате функция записует чтото в А и B масив C отсается пустым.
Помогите найти ошибки. Спасибо!



Автор: Mikl_ 19.6.2009, 03:41
dimas_sceen
Заданы два массива А и В по 20 элементов. Создать массив  С,  элемент  С[i]  которого  равен А[i]-B[i] при A[i]>B[i] и B[i]-A[i] при A[i]<B[i].
Перефорулирую твою задачу if a>=b then a-b>=0 if a<b then a-b<0 отсюда c[i]:=abs(a[i]-b[i])
Код
;pr(M,A,B,C)
;M - размерность массивов
;А - адрес 0-го элемента массива А
;В - адрес 0-го элемента массива В
;С - адрес 0-го элемента массива С
_pr proc far
   push bp
   mov bp,sp 
    push ds
    pusha
    mov cx,[bp+6];размерность массива в байтах но у нас элементы массива слова, 
    shr cx,1; поэтому корректируем содержимое cx 
;хотя если количество элементов известно можно и совсем просто mov cx,20 и никаких параметров в процедуру
    mov si,[bp+8];- адрес 0-го элемента массива А
    mov ax,[bp+10]<-- вот это что за бардак! похоже, что в процедуру ты передаешь пять! параметров а не четыре
    mov ds,ax
    mov bx,[bp+12];адрес 0-го элемента массива В
    mov di,[bp+16];адрес 0-го элемента массива С  
    cld; будем пересылать элементы от младших номеров к старшим  
m1: lodsw; mov ax,[si] si+=2;очередной элемент массива
    sub ax,[bx]; ax:=a[i]-b[i]
    cwd; если ax>=0 dx=0 если ax<0 dx=0FFFFh
    xor ax,dx; если ax>=0 ax не меняется иначе ax:=not ax
    sub ax,dx; если ax>=0 ax не меняется иначе ax:= -ax и тогда ax:=abs(a[i]-b[i])
    stosw; mov [di],ax di+=2
    add bx,2; переходим к следующему элементу массива B    
    loop m1; в цикле обрабатываем массивы A и B
    popa
    pop ds
    pop bp
    retf
_pr endp
 smile как-то так!

Автор: Mikl_ 19.6.2009, 06:20
dimas_sceen
добавь после mov ds,ax строку mov es,ax

Автор: dimas_sceen 19.6.2009, 11:05
Mikl_,
В массив С записует только результат при B[i]>A[i].
A при A[i]>B[i] не записует.


Цитата

Перефорулирую твою задачу if a>=b then a-b>=0 if a<b then a-b<0 отсюда c[i]:=abs(a[i]-b[i])

Немного не так.
Нужно
if a>=b then a-b>=0 
if a<b then b-a>0 

Автор: Mikl_ 19.6.2009, 12:28
dimas_sceen
Я не понял -- моя программа не работает, или ты техзадание меняешь?
Что значит "Нужно
if a>=b then a-b>=0 
if a<b then b-a>0
 

if a>=b then с = a-b = |a - b|
if a<b then c= b-a = -(a-b) = |a - b| smile 


Автор: dimas_sceen 19.6.2009, 13:35
Цитата(Mikl_ @ 19.6.2009,  12:28)
dimas_sceen
Я не понял -- моя программа не работает, или ты техзадание меняешь?
Что значит "Нужно
if a>=b then a-b>=0 
if a<b then b-a>0
 

if a>=b then с = a-b = |a - b|
if a<b then c= b-a = -(a-b) = |a - b| smile

Извини, я нетак понял.
Техзадание тоже. 
От 2 результата функции.

1-й
http://img40.imageshack.us/i/img1s.jpg/

2-й
http://img40.imageshack.us/i/img2h.jpg/

Масив С инициализирован значениями "-1"

Автор: Mikl_ 19.6.2009, 15:01
dimas_sceen
внимательно просмотри текст программы -- у тебя ошибка smile 

Автор: turbanoff 19.6.2009, 15:10
есть предложение, вместо мудреных операций нахождения модуля числа просто, сравнить ax с 0
Код

   cmp ax, 0
   jg m2
   neg ax
 m2:
   ;....

и если надо применить neg

так я считаю, хотя бы понятней....

Автор: dimas_sceen 19.6.2009, 15:55
Цитата(Mikl_ @ 19.6.2009,  15:01)
dimas_sceen
внимательно просмотри текст программы -- у тебя ошибка smile

Код

;********
  .286
;********

PUBLIC _pr

cseg segment PARA 'CODE'
  Assume cs:cseg
;==========================
_pr proc far
   push bp
   mov bp,sp 
    push ds
    pusha
    mov cx,[bp+6];размерность массива в байтах но у нас элементы массива слова, 
    shr cx,1; поэтому корректируем содержимое cx 
;хотя если количество элементов известно можно и совсем просто mov cx,20 и никаких параметров в процедуру
    mov si,[bp+8];- адрес 0-го элемента массива А
    mov ax,[bp+10];<-- вот это что за бардак! похоже, что в процедуру ты передаешь пять! параметров а не четыре
    mov ds,ax
    mov es,ax
    mov bx,[bp+12];адрес 0-го элемента массива В
    mov di,[bp+16];адрес 0-го элемента массива С  
    cld; будем пересылать элементы от младших номеров к старшим  
m1: lodsw; mov ax,[si] si+=2;очередной элемент массива
    sub ax,[bx]; ax:=a[i]-b[i]
    cwd; если ax>=0 dx=0 если ax<0 dx=0FFFFh
    xor ax,dx; если ax>=0 ax не меняется иначе ax:=not ax
    sub ax,dx; если ax>=0 ax не меняется иначе ax:= -ax и тогда ax:=abs(a[i]-b[i])
    stosw; mov [di],ax di+=2
    add bx,2; переходим к следующему элементу массива B    
    loop m1; в цикле обрабатываем массивы A и B
    popa
    pop ds
    pop bp
    retf
_pr endp
 cseg ends
end



Код

#include<dos.h>
#include<stdio.h>
#include<conio.h>
#define M 15
extern void pr(int ,int *,int *,int *);

main()
{
 int A[M],B[M],C[M],i;
 clrscr();
 textcolor(10);
 for(i=0; i<M; i++)
 {
     A[i]=i;
     B[i]=M-i;
     C[i]=-1;
     cprintf("A[%d]= %d B[%d]= %d \n\r",i,A[i],i,B[i]);
 }
 getch();
 /************************/
    pr(M,A,B,C);
 /************************/
 for(i=0; i<M; i++)
 {
     cprintf("A[%d] = \"%d\"     ",i,A[i]);
     cprintf("B[%d] = \"%d\"     ",i,B[i]);
     cprintf("C[%d] = \"%d\" \n\r",i,C[i]);
 }
 getch();




Вроде все правельно, но не работает так как нада   smile 

Автор: Mikl_ 22.6.2009, 08:26
dimas_sceen
убери 16 строку shr cx,1 и будет тебе счатье!

Автор: dimas_sceen 23.6.2009, 13:24
Mikl_
Спасибо за помощь, все работает как нада  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)