Показать полную графическую версию : [решено] реализовать вычисление массива: |S(Ai + Bi)| * X + X^2 , i = 0...3
Всем привет, есть задание реализовать вычисление массива: |S(Ai + Bi)| * X + X^2 , i = 0...3
У меня есть решение, объясните пожалуйста часть кода.
int a[3];
int b[3];
int my_c(int x)
{
int pos,i;
pos=0;
int sum=0;
for(i=0;i<3;i++)
{
pos=i;
{
sum= sum+(a[pos]+ b[i]);
pos++;
}
}
sum=(abs(sum));
sum=(sum*x);
int pow=0;
pow=x*x;
sum= sum+pow;
return sum;
}
Gooch, у тебя код и реализует формулу. Прям линейно по действиям. Сначала находит сумму, затем ее умножает на x, затем x квадрат заменяется через обычное умножение и плюсуется к текущей сумме.
до меня не доходит заполнение массива :(
int pos,i; \\ ввели целочисленные переменные
pos=0; \\ сказали что pos будет 0
int sum=0; \\ почему так? я так понимаю выше мы тоже самое могли сделать? типа int i; int pos=0; или всё таки есть разница?
ну вот че то понять не могу заполнение массива:
for(i=0;i<3;i++) \\ заполняем массив 3 числами, что означает i++? ну и дальше вообще не доходит :(
{
pos=i;
{
sum= sum+(a[pos]+ b[i]);
pos++;
}
}
int sum=0; \\ почему так? я так понимаю выше мы тоже самое могли сделать? типа int i; int pos=0; или всё таки есть разница? »
так решил автор спроси, где брал исходник почему разницы нет
что означает i++? »
увеличение переменной i на 1, т. е. i+1
увеличение переменной i на 1, т. е. i+1 »
то есть он будет прибавлять 1 пока i не станет равна 3?
а что насчет дальше? зачем pos прировняли к i? (a[pos]+ b[i]) что означает данное вырожение?
в данном случае, оно будет прибавлять пока i будет строго меньше 3
что насчет дальше? зачем pos прировняли к i? (a[pos]+ b[i]) что означает данное вырожение? »
откровенно говоря, здесь мне логика не понятна, думаю можно было бы обойтись так
for(i=0;i<3;i++)
sum= sum+(a[pos]+ b[i]);
потому что в теле цикла pos=i, а зачем его увеличивать в конце, если потом все равно pos получает значение i непонятною
здесь реализуется вычисление S(Ai + Bi)
потому что в теле цикла pos=i, а зачем его увеличивать в конце, если потом все равно pos получает значение i непонятною »
то есть pos=i оставляем,а pos++ убираем?
здесь реализуется вычисление S(Ai + Bi) »
щас мозг взорвется...я хочу понять принцип работы этой формулы. Дальше есть следующий код:
int my_assembler(int x)
{
int sum=0;
__asm
{
MOV esi,0
MOV ecx,0
//вычисление суммы массивов
cycle_i:
MOV eax,a[esi]
MOV edx,b[esi]
ADD esi,4
//сумма массивов
ADD sum, eax
ADD sum, edx
INC ecx //увеличивает
CMP ecx, 3 //сравнивает
JB cycle_i //для беззнаковых чисел
//модуль
abso: neg sum
JS abso //переход, если установлен бит знака
//умножаем sum на x
MOV eax,sum
MOV ecx,x
IMUL ecx
MOV sum,eax
//вычисляем квадрат x
MOV eax,x
MOV ecx,x
IMUL ecx
//складываем с суммой квадрат x
ADD sum,eax
}
return sum;
}
void main()
{
int i;
system("title Вычисление значения выражения");
for(int i=0; i<3; i++)
{
printf("Vvedite element A: ");
scanf("%d",&a[i]);
}
for(int i=0; i<3; i++)
{
printf("Vvedite element B: ");
scanf("%d",&b[i]);
}
int x=0;
printf("Vvedite chislo X: ");
scanf("%d",&x);
//printf("C++=%i\n",my_c(x));
printf("Otvet=%i\n",my_assembler(x));
system("pause");
}
задание впринципе решить формулу ассемблерной вставкой, но как я щас понял в этом примере всё решено на С? или что делает код на С? не понимаю :(
__asm
{
MOV esi,0
MOV ecx,0
//вычисление суммы массивов
cycle_i:
MOV eax,a[esi]
MOV edx,b[esi]
ADD esi,4
//сумма массивов
ADD sum, eax
ADD sum, edx
INC ecx //увеличивает
CMP ecx, 3 //сравнивает
JB cycle_i //для беззнаковых чисел
//модуль
abso: neg sum
JS abso //переход, если установлен бит знака
//умножаем sum на x
MOV eax,sum
MOV ecx,x
IMUL ecx
MOV sum,eax
//вычисляем квадрат x
MOV eax,x
MOV ecx,x
IMUL ecx
//складываем с суммой квадрат x
ADD sum,eax
} »
вот это называется ассемблеровской вставкой. она так называется потому что язык программы си, но автор решил что часть кода будет написана на другом допустимом языке - "asm"-е, т.е. ассемблере, о чем явно указывает первая строчка кода в цитате. Компилятор си это допускает.
начнем с того что если ты не знаешь ассемблера смысла объяснять каждую строчку особого нет, описание команд ты можешь посмотреть и в инете, тут никакого секрета нет, коментари в коде подробные.
а вот все что не попало в цитату - это уже чистый си. почему это возможно? все очень просто.
любой компьютер ни коем образом не знает что такое си, бэйсики, и даже ассемблер. он знает только машинный код (готовый exe если понятнее). для того чтобы из языка программирования сделать машинный код (компилировать программу) придумали специальные программы - компиляторы. Они то как раз и знают как из строчек кода на языке сделать машинный код. Естественно компилятор понимает только свой конкретный язык программирования, но ассемблер (любой) настолько приближен к машинному коду что все компиляторы тем или иным образом его знают и могут компилировать вместе со своим родным языком.
вообщем си меня не интересует, что такое компилятор и что такое вставка асемблереная я вкурсе. моя задача решить задание по предмету ассемблер при помощи языка высшего уровня. данная задача это пример решения моего личного задания. хочу понять её решение для того чтоб написать решение своей. в коде сверху, как я уже разобрался, первое решение на языке С, второе на Ассемблере. На данный момент читаю как организовывать массивы в асм.
в данной примере массив не организован на ассемблере, я правда в теле мейна не вижу объявления этих массивов но оно там быть должно.
работа с массивом такова что а и b это начальные адреса (ты это знаешь), и они смещаются на регистр esi как и в си - a[esi] и в цикле этот регистр увеличивается на 4 потому что int обычно занимает 4 байта (но ты же это знаешь).
цикл организован ссылкой которая в ассемблере пишется так - some_name: . Цикл первый до тех пор пока ecx не станет больше (JB) 3 , в теле цикла каждый раз идет INC ecx. Вот и вся работа с массивами, которой собственно и нет.
а вообще в ассемблере массив выделяется так (как пример) - mas db 10 dup (?), где mas - имя массива, db - размер элемента массива, 10 - количество элементов, 0 - чем заполнить.
в данной примере массив не организован на ассемблере »
действительно, по заданию его обозначали на С и вводятся значения с клавиатуры. Кусок кода int my_c(int x)
можно выкинуть.
а вообще в ассемблере массив выделяется так (как пример) - mas db 10 dup (?), где mas - имя массива, db - размер элемента массива, 10 - количество элементов, 0 - чем заполнить. »
вот только такие примеры к сожалению я и нахожу в различных учебниках :(
Beyound огромное спасибо, немного помог мне, до меня что то доходить начало. Был бы очень рад если бы дальше мне помог :)
цикл организован ссылкой которая в ассемблере пишется так - some_name: . Цикл первый до тех пор пока ecx не станет больше (JB) 3 , в теле цикла каждый раз идет INC ecx. »
вот что я понял:
cycle_i: \\ : поставили метку начала цикла
MOV eax,a[esi] \\адрес первого элемента массива а
MOV edx,b[esi] \\адрес первого элемента массива b
ADD esi,4 \\следующий элемент с шагом 4 (т.к. регистр esi имеет размер 4 байта)
ADD sum, eax \\ прибаляем к sum содержимое eax
ADD sum, edx \\ прибавляем к sum содержимое edx
INC ecx \\ увиличение ecx на 1
CMP ecx, 3 \\ проверяет равен ли ecx 3
JB cycle_i \\если ecx < 3 то перейти в начало цикла
Beyound огромнейшее спасибо! очень помог. как заполнять массив я наконец то понял. Щас буду пробывать в своём задании!
у тебя есть пару недочетов
1. CMP ecx, 3 \\ сравниваем ecx 3, итог сравнения эта коменда нам не показывает а хранит его в регистре
2. JB cycle_i \\ команда раскладывается так J - "если сравнение выдало результат" B (bigger) "больше" то переходм по ссылке cycle_i
3.ADD esi,4 \\прибавляем к текущему значению региста esi число 4. 4 потому что все считается в байтах, а нам нужно сместиться на int который занимает 4 байта (32 бита) - это стандартно.
Beyound, а вот моё задание: |S(Ai)*X+S(Bi)*Y|
int sum1=0;
int sum2=0;
___asm
{
mov esi,0
mov ecx,0
cycle_AB:
MOV eax,A[esi]
MOV edx,B[esi]
ADD esi,4
ADD sum1,eax
ADD sum2,edx
INC ecx
CMP ecx,3
JB cycle_AB
MOV eax,sum1
MOV ecx,X
iMUL ecx
MOV sum1,eax
MOV eax,sum2
MOV ecx,Y
iMUL ecx
ADD sum,eax
modyl:
NEG sum
JS modul
}
Правильно ли я его сделал?
если чесно я немного непонимаю как тут операция с массивом идет, не хватает впереди выражения математического знака... или даже двух) вполне возможно что твой вариант верен) по крайней мере ошибок в нем нет
давай так - я тебе напишу логику, а ты сбацаешь на ассемблере. »
ошибку понял :) Я сначала так и хотел сделать, но потом почему то подумал, а почему бы не сделать подругому...
int sum1=0;
int sum2=0;
___asm
{
mov esi,0
mov ecx,0
cycle_A:
MOV eax,A[esi]
ADD esi,4
ADD sum1,eax
INC ecx
CMP ecx,3
JB cycle_A
MOV eax,sum1
MOV ecx,X
iMUL ecx
MOV sum1,eax
mov esi,0
mov ecx,0
cycle_B:
MOV eax,B[esi]
ADD esi,4
ADD sum2,eax
INC ecx
CMP ecx,3
JB cycle_B
MOV eax,sum2
MOV ecx,Y
iMUL ecx
ADD sum1,eax
modul:
NEG sum1
JS modul
}
если чесно я немного непонимаю как тут операция с массивом идет, не хватает впереди выражения математического знака... или даже двух) вполне возможно что твой вариант верен) по крайней мере ошибок в нем нет »
ну вот теперь 2 варианта :) я в первом варианте просто в одном цикле заполнил оба массива без сложения их с друг другом. А так по-моему тоже самое.
Объясни пожалуйста а когда я закончил асемблерную вставку и пишу
return
к чему возврат мне надо указывать? к переменной в которой содержится ответ?
щас проверил и всё замечательно работает! Огромное спасибо!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC