Главная страница
Навигация по странице:

  • «Национальный исследовательский университет ИТМО» Факультет безопасности информационных технологий Дисциплина

  • ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ №2 Поразрядные и логические операции. Выполнил

  • Кудряшов Павел лабораторная 2. Отчет по лабораторной работе 2 Поразрядные и логические операции


    Скачать 82.02 Kb.
    НазваниеОтчет по лабораторной работе 2 Поразрядные и логические операции
    Дата24.03.2022
    Размер82.02 Kb.
    Формат файлаdocx
    Имя файлаКудряшов Павел лабораторная 2.docx
    ТипОтчет
    #413757


    ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

    «Национальный исследовательский университет ИТМО»

    Факультет безопасности информационных технологий

    Дисциплина:

    «Информатика»

    ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ №2

    Поразрядные и логические операции.

    Выполнил:

    Студент группы N3146

    ФИО

    Кудряшов Павел Сергеевич



    Проверил:

    Грозов В.А.

    Санкт-Петербург

    2021г.

    Вариант 6

    Задание: Старшую тетраду каждого байта числа заменить результатом операции «стрелка Пирса» старшей и младшей тетрад, а младшую тетраду – результатом операции «штрих Шеффера» старшей и младшей тетрад исходного байта.

    Блок-схема:



    Текст на Си:

    #include
    // стрелка Пирса :

    (x | y);

    // штрих Шеффера : (x & y);
    void print_bin(int, int);
    int main() {
    unsigned int num = 0xD3;

    unsigned int clearbyte = 0xFF;

    unsigned int tetrada = 0xF;

    unsigned int firsttet = 0x0;

    unsigned int secondtet = 0x0;

    unsigned int tmp = 0x0;

    print_bin(num, 1);
    for (int i = 0; i < 4; i++) { // бежим по каждому байту

    firsttet = (num & (tetrada << i * 8)) >> i * 8; // заносим младшую тетраду

    secondtet = (num & (tetrada << i * 8 + 4)) >> i * 8 + 4; // заносим старшую тетраду

    tmp = firsttet; // сохраняем младшую тетраду

    firsttet = ((secondtet & tmp)) & tetrada;// преобразуем младшую тетраду по штриху Шеффера

    secondtet = ((secondtet | tmp)) & tetrada;// преобразуем старшую тетраду по стрелке Пирса

    num = (num & ((clearbyte << i * 8))) | (firsttet << i * 8) | (secondtet << i * 8 + 4); // обнуляем байт с которым работали и заносим старшую и младшую тетрады.

    }

    print_bin(num, 1);

    return 0;

    }

    // функция для вывода нужного кол-ва байтов

    void print_bin(int a, int byte) {

    for (int i = byte * 8 - 1; i >= 0; i--) printf("%d", (a & (1 << i)) >> i);

    printf("\n");

    }

    Текст на ассемблере:

    section .data

    ; для вывода числа

    one db "1"

    zero db "0"

    binlen equ $-zero

    enofl db 0xA

    ; для алогритма

    num dd 0xA2

    clearbyte dd 0xFF

    tetrada dd 0xF

    section .bss

    ; для вывода числа

    numb resb 4

    iter resb 1

    cutter resb 1

    ; для алогритма

    firsttet resb 4

    secondtet resb 4

    tmp resb 4

    byte_cnt resb 1

    section .text

    ;вывод числа

    printZ:

    mov eax, 4

    mov ebx, 1

    mov ecx, zero

    mov edx, binlen

    int 80h

    ret

    printO:

    mov eax, 4

    mov ebx, 1

    mov ecx, one

    mov edx, binlen

    int 80h

    ret

    printE:

    mov eax, 4

    mov ebx, 1

    mov ecx, enofl

    mov edx, binlen

    int 80h

    ret

    printN:

    cmp eax, 1

    jl zeroN

    call printO

    jmp oneN

    zeroN:

    call printZ

    oneN:

    ret

    printX:

    mov byte[iter], 8

    whileX:

    cmp byte[iter], 1

    jl endX

    mov cl, byte[iter]

    dec cl

    mov eax, dword[numb]

    shr eax, cl

    mov byte[iter], cl

    mov byte[cutter], 1

    call cutnum

    call printN

    jmp whileX

    endX:

    call printE

    ret

    cutnum:

    mov ebx, eax

    mov cl, byte[cutter]

    shr ebx, cl

    shl ebx, cl

    xor eax, ebx

    ret

    ;алгоритм

    global _start

    _start:

    ; вывод начального числа

    mov eax, dword[num]

    mov dword[numb], eax

    call printX

    ; записываем значение счетчика

    mov al, 0

    mov byte[byte_cnt], al

    loop_start:

    ; условие цикла

    cmp al, 4

    jge ex

    ; записываем сдвиг i * 8 в cl

    mov al, byte[byte_cnt]

    mov cl, 8

    mul cl

    mov cl, al

    ; для младшей тетрады

    ; помещаем наше число в eax

    mov eax, dword[num]

    ; tetrada << i * 8 -> заносим в ebx

    mov ebx, dword[tetrada]

    shl ebx, cl

    ; num & ebx заносим в eax

    and eax, ebx

    ; eax >> i * 8 заносим в firsttet

    shr eax, cl

    mov dword[firsttet], eax

    ; для старшей тетрады

    ; помещаем наше число в eax

    mov eax, dword[num]

    ; записываем сдвиг i * 8 + 4 в cl

    add cl, 4

    ; tetrada << i * 8 + 4 -> заносим в ebx

    mov ebx, dword[tetrada]

    shl ebx, cl

    ; num & ebx заносим в eax

    and eax, ebx

    ; eax >> i * 8 + 4 заносим в secondtet

    shr eax, cl

    mov dword[secondtet], eax

    ; сохраняем в tmp младшую тетраду

    mov eax, dword[firsttet]

    mov dword[tmp], eax

    ; преобразуем младшую тетраду по штриху Шеффера

    ; (secondtet & tmp) -> помещаем в eax

    mov eax, dword[secondtet]

    mov ebx, dword[tmp]

    and eax, ebx

    not eax

    ; eax & tetrada (чтобы оставить только одну тетраду) помещаеме в firsttet

    mov ebx, dword[tetrada]

    and eax, ebx

    mov dword[firsttet], eax

    ; преобразуем старшую тетраду по стрелке Пирса

    ; (secondtet | tmp) -> помещаем в eax

    mov eax, dword[secondtet]

    mov ebx, dword[tmp]

    or eax, ebx

    not eax

    ; eax & tetrada (чтобы оставить только одну тетраду) помещаем в secondtet

    mov ebx, dword[tetrada]

    and eax, ebx

    mov dword[secondtet], eax

    ; запись изменения числа

    ; сначала обнуляем байт с которым работали

    ; запишем сдвиг i * 8 в cl

    mov al, byte[byte_cnt]

    mov cl, 8

    mul cl

    mov cl, al

    ; запишем наше число в eax

    mov eax, dword[num]

    ; создадим инвертированную маску 0xFF, чтобы обнулить интересующий нас байт ((clearbyte << i*8)) и запишем ее в ebx

    mov ebx, dword[clearbyte]

    shl ebx, cl

    not ebx

    ; обнулим интересующий нас байт (num & ebx)

    and eax, ebx

    ; установим младшую тетраду на место в нулевом байте

    ; сдвигаем нашу тетраду на нужное место

    mov ebx, dword[firsttet]

    shl ebx, cl

    ; и добавляем к нашему числу

    or eax, ebx

    ; установим старушую тетраду на место в байте с нашей измененной тетрадой

    ; изменим на сдвиг на 4

    add cl, 4

    ; сдвигаем нашу тетраду на нужное место

    mov ebx, dword[secondtet]

    shl ebx, cl

    ; и добавляем к нашему числу

    or eax, ebx

    mov dword[num], eax

    ; переход

    mov al, byte[byte_cnt]

    inc al

    mov byte[byte_cnt], al

    jmp loop_start

    ex:

    ; вывод

    mov eax, dword[num]

    mov dword[numb], eax

    call printX

    ; выход

    mov eax, 1

    xor ebx, 0

    int 0x80

    Дизассемблерный листинг

    Main:

    0000000000001169 <main>:
    1169: f3 0f 1e fa endbr64
    116d: 55 push rbp
    116e: 48 89 e5 mov rbp,rsp
    1171: 48 83 ec 20 sub rsp,0x20
    1175: c7 45 e4 d3 00 00 00 mov DWORD PTR [rbp-0x1c],0xd3
    117c: c7 45 ec ff 00 00 00 mov DWORD PTR [rbp-0x14],0xff
    1183: c7 45 f0 0f 00 00 00 mov DWORD PTR [rbp-0x10],0xf
    118a: c7 45 f4 00 00 00 00 mov DWORD PTR [rbp-0xc],0x0
    1191: c7 45 f8 00 00 00 00 mov DWORD PTR [rbp-0x8],0x0
    1198: c7 45 fc 00 00 00 00 mov DWORD PTR [rbp-0x4],0x0
    119f: 8b 45 e4 mov eax,DWORD PTR [rbp-0x1c]
    11a2: be 01 00 00 00 mov esi,0x1
    11a7: 89 c7 mov edi,eax
    11a9: e8 dc 00 00 00 call 128a <print_bin>
    11ae: c7 45 e8 00 00 00 00 mov DWORD PTR [rbp-0x18],0x0
    11b5: e9 b0 00 00 00 jmp 126a <main+0x101>
    11ba: 8b 45 e8 mov eax,DWORD PTR [rbp-0x18]
    11bd: c1 e0 03 shl eax,0x3
    11c0: 8b 55 f0 mov edx,DWORD PTR [rbp-0x10]
    11c3: 89 c1 mov ecx,eax



    0000000000002058 <__FRAME_END__-0x124>:
    2058: 14 00 adc al,0x0
    205a: 00 00 add BYTE PTR [rax],al
    205c: 00 00 add BYTE PTR [rax],al
    205e: 00 00 add BYTE PTR [rax],al
    2060: 01 7a 52 add DWORD PTR [rdx+0x52],edi
    2063: 00 01 add BYTE PTR [rcx],al
    2065: 78 10 js 2077 <__GNU_EH_FRAME_HDR+0x6f>
    2067: 01 1b add DWORD PTR [rbx],ebx
    2069: 0c 07 or al,0x7
    206b: 08 90 01 00 00 14 or BYTE PTR [rax+0x14000001],dl
    2071: 00 00 add BYTE PTR [rax],al
    2073: 00 1c 00 add BYTE PTR [rax+rax*1],bl
    2076: 00 00 add BYTE PTR [rax],al
    2078: 08 f0 or al,dh
    207a: ff (bad)
    207b: ff 2f jmp FWORD PTR [rdi]
    207d: 00 00 add BYTE PTR [rax],al
    207f: 00 00 add BYTE PTR [rax],al
    2081: 44 07 rex.R (bad)
    2083: 10 00 adc BYTE PTR [rax],al
    2085: 00 00 add BYTE PTR [rax],al
    2087: 00 24 00 add BYTE PTR [rax+rax*1],ah
    208a: 00 00 add BYTE PTR [rax],al
    208c: 34 00 xor al,0x0
    208e: 00 00 add BYTE PTR [rax],al
    2090: 90 nop
    2091: ef out dx,eax
    2092: ff (bad)
    2093: ff 30 push QWORD PTR [rax]
    2095: 00 00 add BYTE PTR [rax],al
    2097: 00 00 add BYTE PTR [rax],al
    2099: 0e (bad)
    209a: 10 46 0e adc BYTE PTR [rsi+0xe],al
    209d: 18 4a 0f sbb BYTE PTR [rdx+0xf],cl
    20a0: 0b 77 08 or esi,DWORD PTR [rdi+0x8]
    20a3: 80 00 3f add BYTE PTR [rax],0x3f
    20a6: 1a 3a sbb bh,BYTE PTR [rdx]
    20a8: 2a 33 sub dh,BYTE PTR [rbx]
    20aa: 24 22 and al,0x22
    20ac: 00 00 add BYTE PTR [rax],al
    20ae: 00 00 add BYTE PTR [rax],al
    20b0: 14 00 adc al,0x0
    20b2: 00 00 add BYTE PTR [rax],al
    20b4: 5c pop rsp
    20b5: 00 00 add BYTE PTR [rax],al
    20b7: 00 98 ef ff ff 10 add BYTE PTR [rax+0x10ffffef],bl
    ...

    Краткий анализ по результатам сравнения:

    Дизассемблированная программа взаимодействует со стеком и сдвиги реализуются не в цикле, в отличие от программы написанной на ассемблере, а «в тупую».







    написать администратору сайта