Важная информация
Показано с 1 по 2 из 2

Тема: Помогите разобраться в коде.

  1. #1 Помогите разобраться в коде. 
    Новичок
    Регистрация
    09.04.2016
    Сообщений
    1
    Сказал(а) спасибо
    0
    Поблагодарили 0 раз(а) в 0 сообщениях
    Суть проблемы:
    учусь на Информатике, первый год. На втором семестре у нас появился предмет "Кпьютерная Архитектура" где нужно писать на Ассемблере, с замечательным преподавателем, который на лабораторных просто сидит и молчит, а на каждый вопрос отвечает -- погуглите, я не могу знать всего. Но разобраться всетаки хочеться.
    Нашел решенные задания с прошлого года, но никак не могу разобраться в коде.
    Прошу, если есть люди которым не лень разжевать мне материал, закоментить каждую строчку кода ассемблера, что там собственно происходит, чтобы я мог разобраться в операторах и что они делают.

    P.S. Не обращайте внимание на Польский язык

    Лист заданий прилагаю:
    1) Замена 4ох заглавных букв на малые.
    2) Замена метами двух 4охбуквенных слов.
    3) Переплетение букв по очереди с двух слов. пример ABCD QWER -> AQBWCEDR
    4) Суммирующая все элементы 3ех элементовой таблицы
    7) Придающая переменной типа "байт" значение 1, если переменная типа "слово" делиться на 16 и значение 0 если не делиться.
    8) Добавляющая переменную D типа байт к первому элементу таблицы состоящей их 4ох элементов, если D делиться на 2, и к четвертому элементу, если D не делиться на два.
    9) Поднесение к девятой степени остаток с деления переменной типа "байт" на 8.


    C++ Code:
    1.  
    2. // Zadanie1
    3.  
    4. #include "stdafx.h"
    5. #include<iostream>
    6. #include<conio.h>
    7. using namespace std;
    8.  
    9. int _tmain(int argc, _TCHAR* argv[])
    10. {
    11. unsigned char a,b,c,d;
    12. cin >> a;
    13. cin >> b;
    14. cin >> c;
    15. cin >> d;
    16.  
    17. _asm
    18. {
    19.  
    20. mov AL, a;
    21. add AL, 32;
    22. mov a, AL;
    23.  
    24. mov AL, b;
    25. add AL, 32;
    26. mov b, AL;
    27.  
    28. mov AL, c;
    29. add AL, 32;
    30. mov c, AL;
    31.  
    32. mov AL, d;
    33. add AL, 32;
    34. mov d, AL;
    35. }
    36. cout << a << b << c << d;
    37. _getch();
    38.     return 0;
    39. }
    40.  
    41.  
    42. //Zadanie2
    43.  
    44. #include "stdafx.h"
    45. #include <iostream>
    46. #include<conio.h>
    47. using namespace std;
    48.  
    49. char napis[4], napis2[4];
    50. int i = 4;
    51. __int32 adr1, adr2, adr3;
    52.  
    53. int _tmain(int argc, _TCHAR* argv[])
    54. {
    55. cout << "Napis 1: ";
    56. cin >> napis;
    57.  
    58. cout << "Napis 2: ";
    59. cin >> napis2;
    60.  
    61. __asm
    62. {
    63. mov AL, napis[0];
    64. mov BL, napis[1];
    65. mov CL, napis[2];
    66. mov DL, napis[3];
    67. mov AH, napis2[0];
    68. mov BH, napis2[1];
    69. mov CH, napis2[2];
    70. mov DH, napis2[3];
    71. mov napis2[0], AL;
    72. mov napis2[1], BL;
    73. mov napis2[2], CL;
    74. mov napis2[3], DL;
    75. mov napis[0], AH;
    76. mov napis[1], BH;
    77. mov napis[2], CH;
    78. mov napis[3], DH;
    79. }
    80. cout << endl << napis << endl;
    81. cin.get();
    82. _getch();
    83. return 0;
    84. }
    85.  
    86.  
    87. //Zadanie3
    88.  
    89. #include "stdafx.h"
    90. #include<iostream>
    91. #include<conio.h.>
    92. using namespace std;
    93.  
    94. char napis[3];
    95. char slowo[3];
    96. char wyraz[6];
    97.  
    98. int _tmain(int argc, _TCHAR* argv[])
    99.  
    100. {
    101. cin >> napis;
    102. cin >> slowo;
    103.  
    104. _asm
    105. {
    106. mov AL, napis[0]
    107. mov wyraz[0], AL
    108.  
    109. mov AL, slowo[0]
    110. mov wyraz[1], AL
    111.  
    112. mov AL, napis[1]
    113. mov wyraz[2], AL
    114.  
    115. mov AL, slowo[1]
    116. mov wyraz[3], AL
    117.  
    118. mov AL, napis[2]
    119. mov wyraz[4], AL
    120.  
    121. mov AL, slowo[2]
    122. mov wyraz[5], AL
    123.  
    124.  
    125.  
    126. }
    127.  
    128. cout << wyraz;
    129.  
    130. _getch();
    131. return 0;
    132. }
    133.  
    134.  
    135. //Zadanie4
    136.  
    137. cout « "Write 1st element: ";
    138. cin » tab[0];
    139. cout « "Write 2nd element: ";
    140. cin » tab[1];
    141. cout « "Write 3rd element: ";
    142. cin » tab[2];
    143.  
    144. int result = 0;
    145.  
    146. __asm
    147. {
    148. mov EAX, offset tab;
    149. xor EBX, EBX;
    150.  
    151. add BX, [EAX];
    152. add BX, [EAX + 2];
    153. add BX, [EAX + 4];
    154.  
    155. mov result, EBX;
    156. }
    157.  
    158. cout « "The result is = " « result;
    159. _getch();
    160.  
    161.  
    162. //zadanie 7
    163.  
    164. #include "stdafx.h"
    165. #include<iostream>
    166. #include<conio.h>
    167.  
    168. using namespace std;
    169.  
    170. int main()
    171. {
    172. short numer;
    173. cout << "Napisz swoj numer: ";
    174. cin >> numer;
    175. short result = 0;
    176. __asm {
    177. mov AX, numer;
    178. mov BX, 16;
    179. xor DX, DX;
    180. div bx;
    181. mul bx;
    182.  
    183. mov bx, numer;
    184. div bx;
    185.  
    186. mov result, AX;
    187. }
    188. cout << "Odpowiedz:" << result;
    189. _getch();
    190. }
    191.  
    192.  
    193.  
    194. //zadanie 8
    195.  
    196. #include "stdafx.h"
    197. #include<iostream>
    198. #include<conio.h>
    199.  
    200. using namespace std;
    201.  
    202. int main()
    203. {
    204. char tab1[3];
    205. short int tab[4] = { 1, 2, 3, 4 };
    206. __int8 input;
    207.  
    208. cout << "Napisz swoj numer: " << endl;
    209. cin >> input;
    210. cout << "The tab is: " << tab1[0] << ";" << tab1[1] << ";" << tab1[2] << ";" << tab1[3] << endl;
    211.  
    212. __asm
    213. {
    214. xor EAX, EAX;
    215. mov AL, input;
    216. mov EBX, offset tab1;
    217. add EBX, 6;
    218. and AL, 1;
    219. mov CL, 6;
    220. mul CL;
    221. sub EBX, EAX;
    222. xor ECX, ECX;
    223. mov CL, input;
    224. add[EBX], ECX;
    225. }
    226. cout << "Odpowiedz: " << tab1[0] << " tab 1 = " << tab1[1] << "tab 2 = " << tab1[2] << "Tab 3 = " << tab1[3];
    227. _getch();
    228.  
    229. return 0;
    230. }
    231.  
    232.  
    233. //Zadanie9
    234.  
    235. #include "stdafx.h"
    236. #include<iostream>
    237. #include<conio.h.>
    238. using namespace std;
    239.  
    240.  
    241.  
    242. int main()
    243. {
    244. __int8 number;
    245. cout << "Napish symbol: " << endl;
    246. cin >> number;
    247. cout >> "Nomer symbolu: " << int(number) << endl;
    248. int result;
    249.  
    250. __asm
    251. {
    252. mov EAX, 0;
    253. mov AL, number;
    254. and AL, 7;
    255.  
    256. mov EBX, EAX;
    257. mul EBX;
    258. mul EBX;
    259.  
    260. mov EBX, EAX;
    261. mul EBX;
    262. mul EBX;
    263.  
    264.  
    265. mov result, EAX;
    266. }
    267. cout << "Rezultat: " << result;
    268. _getch();
    269. }
    Ответить с цитированием  
     

  2. #2  
    Супер модератор Аватар для >Quiet Snow<
    Регистрация
    11.04.2011
    Адрес
    Планета земля
    Сообщений
    3,927
    Сказал(а) спасибо
    1,842
    Поблагодарили 982 раз(а) в 840 сообщениях
    Записей в блоге
    1
    1.
    Замена 4ох заглавных букв на малые.
    Задание бесполезно без указания кодировки.

    Assembler Code:
    1. mov AL, a    ; в регистр AL (младшая 8 битная часть 16 битного регистра AX) загруз. знач. из памяти
    2. add AL, 32   ;  прибавить к регистру AL значение 32
    3. mov a, AL    ;  отослать обратно в ту же переменную

    Сработает это только для стандартного 7 бит ASCII.
    Перед тем как преобразовывать, нужно понять, действительно ли буква заглавная,
    потому что если она не заглавная - то код выдаст нам совсем не то, что ожидается.

    2.

    Assembler Code:
    1. mov AL, napis[0]    ;  Перебрасываем napis в регистры al, bl, cl, dl поочерёдно
    2. mov BL, napis[1]    ;
    3. mov CL, napis[2]    ;
    4. mov DL, napis[3]    ;
    5. mov AH, napis2[0]   ;  Перебрасываем napis2 в регистры ah, bh, ch, dh
    6. mov BH, napis2[1]   ;  ( это старшие 8 бит соотв. 16 битных регистров(ax, bx, cx, dx) )
    7. mov CH, napis2[2]   ;
    8. mov DH, napis2[3]   ;
    9. mov napis2[0], AL   ;  Перебрасываем регистры al, bl, cl, dl в napis2
    10. mov napis2[1], BL   ;
    11. mov napis2[2], CL   ;
    12. mov napis2[3], DL   ;
    13. mov napis[0], AH    ;  Перебрасываем регистры ah, bh, ch, dh в napis
    14. mov napis[1], BH    ;
    15. mov napis[2], CH    ;
    16. mov napis[3], DH    ;

    Процедура сделана очень медленно. Процессор может менять целые двойные слова(тип DWORD = 32 бита).

    Обмен можно сделать так:
    Assembler Code:
    1.   Mov    eax, dword ptr [napis]   ;  В eax кладём 32 бита из памяти(массив букв) napis
    2.   Xchg   eax, dword ptr [napis2]  ;  Обмен 32 бит napis2 с регистром eax
    3.   Mov    dword ptr [napis], eax   ;  eax отправляем обратно в память napis

    Не знаю, что у вас за компилятор, синтаксис может немного отличаться, подправите если что.

    3.
    Ваше задание 3 нерабочее. Даже не проверяя кода видно, что пересылка 6-ти байт, а не 8-ми.
    Сделать его можно десятками способов. Например, можно читать по байту через LodSb и
    раскидывать по расширенным регистрам(используя побитовый сдвиг), а потом сгрузить регистр
    в массив символов. Тут ваш препод полностью прав, нужно действительно плотно погуглить и
    посмотреть, что процессоры могут предоставить наиболее оптимальное для данной задачи.

    4.

    Не вижу типов переменных для tab. Тут вы можете увидеть, как используется ключевое слово
    Offset. Это MASM. Вижу косяк. Во-первых, элементы массива не соответствуют по типу с суммируемой
    переменной, а во-вторых, при переполнении BX результат будет неверный(т.к. отдаём EBX).
    Эту задачу специально сделаю в правильном варианте. Пишу на FB (си есть в виде DEV-C++, но не
    хочу с ним париться, суть вы и так поймёте).

    FreeBasic Code:
    1. DIM tabl(2) AS SHORT    ' 16 бит знаковые, массив 3 элемента
    2. DIM result AS LONG      ' 32 бит знаковые
    3.  
    4. CLS                     '   Очистим экран
    5. INPUT "Zn 1 :", tabl(0) '   Введём с клавиатуры значения
    6. INPUT "Zn 2 :", tabl(1)
    7. INPUT "Zn 3 :", tabl(2)
    8.  
    9. ASM
    10.    Lea esi, [tabl]      '  Смещение положим в esi
    11.    Xor ebx, ebx         '  Обнулим ebx
    12.    Xor eax, eax         '  Обнулим eax
    13.  
    14.    LodSw                '  Загрузим 2 байта (в ax с esi)
    15.    Add ebx, eax         '  Добавим к bx то, что лежит в eax
    16.    LodSw                '  Загрузим 2 байта
    17.    Add ebx, eax         '  Добавим к bx то, что лежит в eax
    18.    LodSw                '  Загрузим 2 байта
    19.    Add ebx, eax         '  Добавим к bx то, что лежит в eax
    20.  
    21.    Mov [result], ebx    '  Результат в переменную
    22. END ASM
    23.  
    24. PRINT result            '  Результат на экран
    25. SLEEP                   '  Ожидаем нажатия кнопки


    Суть в том, что если вы оставите код как у вас, то при переполнении число просто полезет с другого края
    диапазона(на беззнаковых числах объясняется просто, предел 16 бит 65535, выход за него будет переведён
    в число, отсчитывающееся от нуля, на знаковых числах это уже сложнее, т.к. используется дополнительный код).

    7.

    В седьмом вашем задании какая-то каша. Увидев div, а следом mul, даже не стал разгребать эти нечистоты,
    они того точно не стоят.
    Вас попросили узнать есть ли остаток от деления на 16, можно, собcтвенно, это сделать командой div,
    которая вернёт результат деления и остаток, для этого нужно специальным образом заготовить регистры
    и вызвать команду div (читайте в любом справочнике по ассемблеру).

    Сделаю тоже, чтобы вы понимали:
    FreeBasic Code:
    1. DIM Ok AS BYTE         ' 1 - Если делится    0 - Не делится
    2. DIM Perem AS USHORT    ' 16 бит беззнаковое
    3. CLS
    4.  
    5. INPUT "Vvedite delimoe: ", Perem
    6.  
    7. ASM
    8.    Xor dx, dx         '  Обнулим dx
    9.    Mov cx, 16         '  То, на что делим
    10.    Mov bl, dl         '  Наш флаг обнулён
    11.    Mov ax, [Perem]    '  Само делимое
    12.    Div cx             '  Делим, в dx вернётся остаток, в ax - результат деления
    13.    Test dx, dx        '  Конъюнкция и сравнение, для установки флагов процессора
    14.    Jnz NoFlag         '  Если dx не равен нулю то прыгаем на метку и не ставим наш флаг
    15.    Inc bl             '  Наш флаг в 8 бит регистре = 1
    16. NoFlag:
    17.    Mov [Ok], bl       '  Запишем его в переменную
    18. END ASM
    19.  
    20. PRINT "flag = "; Ok
    21. SLEEP


    Но можно это сделать элегантнее, через логические операции. Т.к. если вы заметили нас интересует нижняя
    половина регистра al, т.к. если она не равна нулю - это значит что деление по любому будет с остатком.
    Этот вариант мало того что короче, так он ещё не использует тяжёлые по тактам операции (деление\умножение):

    FreeBasic Code:
    1. DIM Ok AS BYTE         ' 1 - Если делится    0 - Не делится,  8 бит знаковое
    2. DIM Perem AS USHORT    ' 16 бит беззнаковое
    3. CLS
    4.  
    5. INPUT "Vvedite delimoe: ", Perem
    6.  
    7. ASM
    8.    Xor cl, cl         '  Обнулим флаг
    9.    Mov ax, [Perem]    '  Само делимое
    10.    And ax, &B1111     '  Выделяем биты (флаги после этой операции уже стоят)
    11.    Jnz NoFlag         '  Если dx не равен нулю то прыгаем на метку и не ставим флаг
    12.      Inc cl           '  Наш флаг в 8 бит регистре = 1
    13. NoFlag:
    14.    Mov [Ok], cl       '  Запишем флаг в переменную
    15. END ASM
    16.  
    17. PRINT "flag = "; Ok
    18. SLEEP


    Последние два задания, предлагаю вам разобрать в данной теме самостоятельно и если что-то у вас пойдёт
    не так, постараемся подправить. Ассемблерщиков тут много, помогут 100%.
    Последний раз редактировалось >Quiet Snow<; 10.04.2016 в 05:46.
    Обучение прикладному программированию(по skype), качественно, недорого, 18+, вопросы в личку.
    «Если вы ничего не сделаете, я уверяю вас, ничего и не произойдёт» © Жак Фреско
    Ограниченно модерирую.
    Ответить с цитированием  
     

  3. Пользователь сказал cпасибо:

    Free Admin (10.04.2016)

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. джумлокеш помогите разобраться)
    от dotcom в разделе Общие вопросы web-разработки
    Ответов: 2
    Последнее сообщение: 09.07.2015, 13:39
  2. Помогите, пожалуйста, разобраться
    от Marisha в разделе Сети
    Ответов: 0
    Последнее сообщение: 14.01.2014, 15:49
  3. Помогите разобраться,в чем ошибка!(((
    от Мариночка в разделе C/C++
    Ответов: 4
    Последнее сообщение: 25.11.2013, 01:28
  4. Помогите разобраться с GW-BASIC
    от stamos в разделе Basic
    Ответов: 6
    Последнее сообщение: 20.12.2011, 10:23
  5. Помогите разобраться с QBASIC
    от Лёха в разделе QBasic
    Ответов: 1
    Последнее сообщение: 05.09.2011, 19:23
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •