Форум программистов, компьютерный форум, киберфорум
Наши страницы
Assembler для начинающих
Войти
Регистрация
Восстановить пароль
 
 
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
#1

Вычисление целочисленного арифметического выражения (Ассемблерная вставка) - Assembler

05.03.2018, 13:45. Просмотров 858. Ответов 22
Метки нет (Все метки)

Пожалуйста. Помогите. Напишите, пожалуйста, ассемблеровскую вставку (вообще не понимаю как она работает, а нужно срочно, не успею разобраться).

Условие Такое:
v = ((-y+x*(3*z+1))/(z-2)+1
z, y-байты
x, v-слова
Написать программу, которая вычисляет значение выражения с помощью стандартных арифметических операций языка С и с помощью ассемблерной вставки. Проверить на двух тестовых наборах.
1) x = -2h; y = 7h; z= 3h; v= -1Ah;
2) x = FBEh; y = 56h; z = -7Fh; v = 2E60h;

Далее идет Стандартный код программы (на языке Си), но подстроен он под другое условие. Можете просто подкорректировать эту программу под вышеописанные условия. Больше ничего

C
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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <locale.h>
#include <string.h>
 
short int as(char x, char y, short int z)
{
short int v_as = 0;
__asm
{//Cчитаем числитель
mov ax, z;//перенесли z в ax
add ax, 3;// прибавили 3 (=-1)
mov bx, ax;//перенесли ax в bx
mov al, 5;//перенесли 5 в al
cbw;//расширили 5 до слова
imul bx;//перемножили 5 и z-1 (=-5)
mov bx, ax;//перенесли ax в bx
mov cx, dx;//перенесли cx в dx
mov al, x;//перенесли х в al
cbw;//расширили х до слова
cwd;//расширили х до двойного слова
add dx, cx;//сложили старшие слова
add bx, ax;//сложили младшие слова
//Считаем знаменатель
mov al, y;//перенесли у в al
cbw;//расширили до слова
dec ax;//вычитаем 1 из н
xchg ax, bx;//меняем местами bx и ax
idiv bx;// делим на слово
add ax, 3;//складываем ax с 3
mov v_as, ax;//переносим ax в v_as
}
return v_as;
}
 
 
int main()
{
short int as(char x, char y, short int z);
setlocale(LC_ALL, "rus");
setlocale(LC_NUMERIC, "eng");
short int  v_as1, v_c1;
   short int v_as2, v_c2;
short int v1 = 0x2;
short int v2 = -0x3C2;
printf("Результаты работы программы:\n");
printf("Первый тестовый набор:\n");
v_as1 = as(-0x2, 0x8, -0x4);
v_c1 = ((-0x2 + 5*(-0x4 + 3)) / (0x8 - 1)) + 3;
printf("v_c = %X (16 система) или %d (10 система)\n", v_c1, v_c1);
printf("v_as = %X (16 система) или %d (10 система)\n", v_as1, v_as1);
printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v1, v1);
printf("Второй тестовый набор:\n");
v_as2 = as(0x4A, -0x7C, 0x5E3A);
v_c2 = (0x4A + 5 * (0x5E3A + 3)) / (-0x7C - 1) + 3;
printf("v_c = %X (16 система) или %d (10 система)\n", v_c2, v_c2);
printf("v_as = %X (16 система) или %d (10 система)\n", v_as2, v_as2);
printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v2, v2);
return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.03.2018, 13:45
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Вычисление целочисленного арифметического выражения (Ассемблерная вставка) (Assembler):

Вычисление целочисленного арифметического выражения (Ассемблерная вставка)
Мой проект должен решать уравнение ;(3*c+8-d)/(a-c/4) для беззнаковых чисел на...

Вычисление целочисленного арифметического выражения (Ассемблерная вставка)
Приветствую. Форумчане, покажите на ошибку в коде. Ответ не совпадает с...

Вычисление целочисленного арифметического выражения (Ассемблерная вставка)
имеется код, который необходимо подкорректировать, с чем не справляюсь. что бы...

Вычисление целочисленного арифметического выражения (Ассемблерная вставка)
Приветствую! Есть небольшая проблемка, во вставке должно считаться значение...

Вычисление целочисленного арифметического выражения (Ассемблерная вставка)
Где ошибка?((( v=(((z-4)*y+x)/(7*x-6))-1, где y,v-слова x,z-байты ...

Вычисление целочисленного арифметического выражения (Ассемблерная вставка в C++)
помогите пожалуйста написать вставку для вычисления значения следующего...

22
Estimable
9 / 9 / 1
Регистрация: 02.01.2017
Сообщений: 103
07.03.2018, 11:13 #2
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
mov ax,0;чтоб не расширять
mov dx,3
mov bx,0
 
 
mov al,z
 
mov bl,al;копия для знаменателя
imul dl                                   
inc al
;------------------------------
 
mov cl,x
xchg ax,cx
cbw
xchg cx,ax
imul cx
 
xor cx,cx
 
mov cl,y
xchg ax,cx
cbw
xchg cx,ax
 
 
sub ax,cx
 
;----------------------------------
 
dec bl
;;;;;;;;;;;;;;;;;;;
mov dx,0;подготовить к делению
 
;;;;;;;;;;;;;;
idiv bl
mov v_as, ax
где-то помарка, наверно очерёдность действий не правильна.

Добавлено через 3 минуты
Напиши мне циферками очерёдность действий в выражении.
я понял так:
0)3*z
1)(3*z+1)
2)x*(3*z+1)
3)-y+x*(3*z+1)
4)(z-2)
5)(z-2)+1
6)((-y+x*(3*z+1)) / (z-2)+1
0
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
12.03.2018, 21:06  [ТС] #3
Нужна срочная помощь. Сделайте, пожалуйста, программу по нижеописанному условию. Специально даю код, но под другое условие, чтобы вам было легче (тупо подкорректировать этот код под указанное условие, это не займёт много времени). Вы мне очень поможете; к сожалению сам вообще не понимаю как ассемблер работает, времени разобраться совсем нет (((
Условие Такое:
v = ((-y+x*(3*z+1))/(z-2)+1
z, y-байты
x, v-слова
Написать программу, которая вычисляет значение выражения с помощью стандартных арифметических операций языка С и с помощью ассемблерной вставки. Проверить на двух тестовых наборах.
1) x = -2h; y = 7h; z= 3h; v= -1Ah;
2) x = FBEh; y = 56h; z = -7Fh; v = 2E60h;

Код, но под другое условие:
C
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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <locale.h>
#include <string.h>
 
short int as(char x, char y, short int z)
{
short int v_as = 0;
__asm
{//Cчитаем числитель
mov ax, z;//перенесли z в ax
add ax, 3;// прибавили 3 (=-1)
mov bx, ax;//перенесли ax в bx
mov al, 5;//перенесли 5 в al
cbw;//расширили 5 до слова
imul bx;//перемножили 5 и z-1 (=-5)
mov bx, ax;//перенесли ax в bx
mov cx, dx;//перенесли cx в dx
mov al, x;//перенесли х в al
cbw;//расширили х до слова
cwd;//расширили х до двойного слова
add dx, cx;//сложили старшие слова
add bx, ax;//сложили младшие слова
//Считаем знаменатель
mov al, y;//перенесли у в al
cbw;//расширили до слова
dec ax;//вычитаем 1 из н
xchg ax, bx;//меняем местами bx и ax
idiv bx;// делим на слово
add ax, 3;//складываем ax с 3
mov v_as, ax;//переносим ax в v_as
}
return v_as;
}
 
 
int main()
{
short int as(char x, char y, short int z);
setlocale(LC_ALL, "rus");
setlocale(LC_NUMERIC, "eng");
short int  v_as1, v_c1;
   short int v_as2, v_c2;
short int v1 = 0x2;
short int v2 = -0x3C2;
printf("Результаты работы программы:\n");
printf("Первый тестовый набор:\n");
v_as1 = as(-0x2, 0x8, -0x4);
v_c1 = ((-0x2 + 5*(-0x4 + 3)) / (0x8 - 1)) + 3;
printf("v_c = %X (16 система) или %d (10 система)\n", v_c1, v_c1);
printf("v_as = %X (16 система) или %d (10 система)\n", v_as1, v_as1);
printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v1, v1);
printf("Второй тестовый набор:\n");
v_as2 = as(0x4A, -0x7C, 0x5E3A);
v_c2 = (0x4A + 5 * (0x5E3A + 3)) / (-0x7C - 1) + 3;
printf("v_c = %X (16 система) или %d (10 система)\n", v_c2, v_c2);
printf("v_as = %X (16 система) или %d (10 система)\n", v_as2, v_as2);
printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v2, v2);
return 0;
}
0
ФедосеевПавел
Модератор
3418 / 1915 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
14.03.2018, 10:07 #4
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
;v = ((-y+x*(3*z+1))/(z-2)+1 
;z, y-байты 
;x, v-слова
 
;знаменатель
mov al, z
cbw
sub ax, 2
mov cx, ax
;числитель
mov al, 3
imul [z]
add ax, 1
imul [x]
sub al, [y]
sbb ah, 0
sbb dx, 0
 
idiv cx
 
add ax, 1
0
Estimable
9 / 9 / 1
Регистрация: 02.01.2017
Сообщений: 103
15.03.2018, 10:37 #5
Вот ещё переделал под сопроцессор. Но x,y,z,v должны иметь размер в 4байта - это минимум для сопроцессора.
И непосредственные значения(цифры 3,2,1 в формуле )должны тоже хранится в памяти(у меня цифра 3 в ячейке three, 2 в ячейке two), кроме единицы, которая загружается коммандой.

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fld1 ;  загрузить единицу в регистр
fild z ;загрузить переменную z в регистр выше
fld st; скопировать z в регистр выше(для знаменателя)
fimul three;умножить z на самый верхний регистр
fadd st,st(2);сложить самый верхний регистр с единицей которая через один регистр ниже
fimul x;умножить самый верхний регистр на x
fisub y;отнять самый верхний регистр от y
 
 
fxch st(1);поменять верхний регистр(в котором накопили числитель),на второй(в котором будем копить знаменатель)
fisub two;отнять 2 от копии z (которая теперь в самом верхнем регистре)
fadd st,st(2);сложить самый верхний регистр с единицей(которую ещё загрузили в начале)
fdivr st,st(1);разделить числитель на знаменатель
fst v;вывести в v (можно fist v для недробного числа)
Тут всё проще и без заморочек, лишь нужно правильно определить типы данных.

ps: правда считал формулы в том же самом порядке(
0
Uncle Remus
Заблокирован
15.03.2018, 11:49 #6
Цитата Сообщение от Estimable Посмотреть сообщение
Но x,y,z,v должны иметь размер в 4байта - это минимум для сопроцессора
Estimable,
а ещё FPU может работать с двухбайтными целыми (FIADD, FISUB, FISUBR, FIMUL, FIDIV, FIDIVR)
0
Jin X
❗❗ RTFM 👈
4007 / 1151 / 151
Регистрация: 14.12.2014
Сообщений: 2,290
Записей в блоге: 5
Завершенные тесты: 2
16.03.2018, 09:44 #7
А ещё AVX-512 позволяет работать (конвертировать) с 2-байтовыми вещественными числами (половинной точности)
2
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
18.03.2018, 15:33  [ТС] #8
Это и есть код? Какой-то он некорректный, что ли
0
ФедосеевПавел
Модератор
3418 / 1915 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
18.03.2018, 20:44 #9
Почему? Зуб даёшь!!?

Добавлено через 2 минуты
А-а-а! Понял!
Я читать умею
Цитата Сообщение от GrihanS Посмотреть сообщение
Условие Такое:
v = ((-y+x*(3*z+1))/(z-2)+1
z, y-байты
x, v-слова
А вы, уважаемый - не умеете
Цитата Сообщение от GrihanS Посмотреть сообщение
C
6
short int as(char x, char y, short int z)
Добавлено через 17 минут
Ещё, думаю, что вы не умеете пользоваться C/C++ в разделе формата вывода.
Разберитесь с форматом вывода знаковых шестнадцатеричных данных в printf.

Зуб - в студию!

Добавлено через 4 часа 27 минут
masm32
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
.686P
.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\masm32.inc
 
        includelib d:\masm32\lib\user32.lib
        includelib d:\masm32\lib\kernel32.lib
        includelib d:\masm32\lib\masm32.lib
.data
        aszMsgResult    db      0Dh, 0Ah, 'Result: ', 0Dh, 0Ah, 0
        aszCrLf         db      0Dh, 0Ah, 0
        aszPressEnter   db      0Dh, 0Ah, 0Dh, 0Ah, "Press ENTER to exit", 0
 
        x       dw      0fbeh
        y       db      56h
        z       db      -7fh
        v       dw      0
        aszHex          db      '%Xh', 0
.data?
        hConsoleOutput  HANDLE  ?
        hConsoleInput   HANDLE  ?
        Buffer          db      1024 dup(?)
        BufLen          dd      ?
        lpBuffer        dd      ?
.code
 
as      proc    xx:word, yy:byte, zz:byte
        push    ecx
        push    edx
        ;v = ((-y+x*(3*z+1))/(z-2)+1
        ;z, y-байты
        ;x, v-слова
 
        ;знаменатель
        mov     al, [zz]
        cbw
        sub     ax,     2
        mov     cx,     ax
        ;числитель
        mov     al,     3
        imul    [zz]
        add     ax,     1
        imul    [xx]
        sub     al,     [yy]
        sbb     ah,     0
        sbb     dx,     0
 
        idiv    cx
 
        add     ax,     1
 
        pop     edx
        pop     ecx
        ret
as      endp
 
PrintSignedHex  proc
        lea     esi,    [Buffer]
        mov     [BufLen],       0
        or      eax,    eax
        jns     @@Positive
        neg     eax
        mov     [esi],  byte ptr '-'
        inc     esi
@@Positive:
        invoke  wsprintf, esi, ADDR aszHex, eax
        invoke  StrLen, ADDR Buffer
        mov     [BufLen],       eax
        invoke  WriteConsole, hConsoleOutput, ADDR Buffer,\
                BufLen, ADDR BufLen, NULL
        ret
PrintSignedHex  endp
 
start   proc
        ; получение описателей ввода и вывода консоли
        invoke  GetStdHandle,   STD_INPUT_HANDLE
        mov     hConsoleInput,  eax
 
        invoke  GetStdHandle,   STD_OUTPUT_HANDLE
        mov     hConsoleOutput, eax
 
        invoke  ClearScreen
 
        invoke  as,     [x], [y], [z]
        mov     [v],    ax
 
        ;вывод результата
        invoke  WriteConsole, hConsoleOutput, ADDR aszMsgResult,\
                LENGTHOF aszMsgResult - 1, ADDR BufLen, NULL
 
        mov     ax,     [v]
        cwde
        invoke  PrintSignedHex
 
        invoke  WriteConsole, hConsoleOutput, ADDR aszCrLf,\
                LENGTHOF aszCrLf - 1, ADDR BufLen, NULL
 
        ;ожидание нажатия ENTER
        invoke  WriteConsole, hConsoleOutput, ADDR aszPressEnter,\
                LENGTHOF aszPressEnter - 1, ADDR BufLen, NULL
        invoke  ReadConsole, hConsoleInput, ADDR Buffer,\
                LENGTHOF Buffer, ADDR BufLen, NULL
 
        invoke  ExitProcess, 0
start   endp
 
end     start
0
Estimable
9 / 9 / 1
Регистрация: 02.01.2017
Сообщений: 103
19.03.2018, 12:08 #10
Цитата Сообщение от ФедосеевПавел Посмотреть сообщение
add ax, 1
А что даёт именно такая комманда? а не inc ax?
1
ФедосеевПавел
Модератор
3418 / 1915 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
19.03.2018, 16:44 #11
Estimable, можно и так. Наверно и быстрее и короче. Делал на рефлексах, как акын - что видел, о том и пел.
В голове постоянно держал возможность сложения регистровых пар (необходимость корректного флага CY) и делал обычными арифметическими командами. Инструкция inc не влияет на CY.
0
Uncle Remus
Заблокирован
19.03.2018, 17:54 #12
ФедосеевПавел,
а еще для сложения можно использовать LEA
1
ФедосеевПавел
Модератор
3418 / 1915 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
19.03.2018, 18:04 #13
И на 3, 5 умножать.
0
Jin X
❗❗ RTFM 👈
4007 / 1151 / 151
Регистрация: 14.12.2014
Сообщений: 2,290
Записей в блоге: 5
Завершенные тесты: 2
19.03.2018, 18:45 #14
На 2, 3, 4, 5, 8 и 9
1
ФедосеевПавел
19.03.2018, 18:48
  #15

Не по теме:

Нужно будет переработать примеры преобразования строки в число :)

0
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
20.03.2018, 18:40  [ТС] #16
Пацаны, не работает прога, ответ выдаёт неверный
C
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
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <locale.h>
#include <string.h>
 
short int as(char x, char y, short int z)
{
short int v_as = 0;
__asm
{ //Cчитаем числитель
mov ax,0; //чтоб не расширять
mov dx,3;
mov bx,0;
mov al,z;
mov bl,al; //копия для знаменателя
imul dl;                                  
inc al;
mov cl,x;
xchg ax,cx
cbw;
xchg cx,ax;
imul cx;
xor cx,cx;
mov cl,y;
xchg ax,cx;
cbw;
xchg cx,ax;
sub ax,cx;
dec bl;
mov dx,0; //подготовить к делению
 idiv bl;
mov v_as, ax; //переносим ax в v_as
}
return v_as;
}
 
int main()
{
​short int as(char x, char y, short int z);
​setlocale(LC_ALL, "rus");
​setlocale(LC_NUMERIC, "eng");
​short int v_as1, v_c1;
short int v_as2, v_c2;
​short int v1 = -0x1A;
​short int v2 = 0x2E60;
​printf("Результаты работы программы:\n");
​printf("Первый тестовый набор:\n");
​v_as1 = as(-0x2, 0x7, 0x3);
​v_c1 = ((-0x7 + -0x2*(3*0x3 + 1)) / (0x3 - 2)) + 1;
​printf("v_c = %X (16 система) или %d (10 система)\n", v_c1, v_c1);
​printf("v_as = %X (16 система) или %d (10 система)\n", v_as1, v_as1);
​printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v1, v1);
​printf("Второй тестовый набор:\n");
​v_as2 = as(0x4A, -0x7C, 0x5E3A);
​v_c2 = ((-0x56 + 0xFBE*(3*-0x7F + 1)) / (-0x7F - 2)) + 1;
​printf("v_c = %X (16 система) или %d (10 система)\n", v_c2, v_c2);
​printf("v_as = %X (16 система) или %d (10 система)\n", v_as2, v_as2);
​printf("Должно получиться v = %X (16 система) или %d (10 система)\n", v2, v2);
​return 0;
}
Добавлено через 2 минуты
Не работает прога, пацаны
0
Jin X
❗❗ RTFM 👈
4007 / 1151 / 151
Регистрация: 14.12.2014
Сообщений: 2,290
Записей в блоге: 5
Завершенные тесты: 2
20.03.2018, 18:40 #17
GrihanS, вам же модератор исправил уже первое сообщение и написал о необходимости использования кнопок/тегов форматирования исходников [ASM][/ASM] или [CPP][/CPP] или [CLANG][/CLANG], зачем второй раз так же пишете?
0
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
20.03.2018, 18:43  [ТС] #18
Да, ясно, не заметил
0
ФедосеевПавел
Модератор
3418 / 1915 / 815
Регистрация: 01.02.2015
Сообщений: 6,454
20.03.2018, 19:35 #19
GrihanS, вы читать умеете?
Я уже в сообщении объяснил причины неправильных результатов.
Привёл код полностью на ассемблере с выделением вычислений в процедуру и обработкой вывода для правильных результатов.

Сделать в VC не могу - нет у меня VC.
Что ещё не ясно?
Следующий вариант для вас - подойти к преподавателю и показать эту тему - он подскажет дальше.

В этой теме отвечать больше не собираюсь.
Всего хорошего.
0
GrihanS
0 / 0 / 0
Регистрация: 04.03.2018
Сообщений: 7
20.03.2018, 20:00  [ТС] #20
Вы эт, успокойтесь, ваш код, кстати, тоже не запускается, совсем, как ни пробовал; так что, пойду я.
0
20.03.2018, 20:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2018, 20:00
Привет! Вот еще темы с решениями:

Вычисление целочисленного арифметического выражения (Ассемблерная вставка в C++)
Добрый вечер, задание - вычислить выражения (тип данных signed byte)...

Вычисление арифметического выражения (ассемблерная вставка)
v=-3-\frac{ (x+5)(y-4)-3}{ z+3 } где z-байт, x,y,v-слова Решила сначала начать...

Вычисление целочисленного арифметического выражения
1) операции выполнить при использование арифметических команд...

Вычисление целочисленного арифметического выражения
помогите пожалуйста написать программу для решения примера X=5*(A-B)+2*C A,...


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

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

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