Обмен битов местами по схеме 1->2->3->14->1 - Assembler

Узнай цену своей работы

Формулировка задачи:

Добрый день, хотелось бы разобраться как сделать так, чтобы пользователь ввёл строку с чётным числом символов, а программа группировала символы и рассматривала эти пары как слова по 16 бит, но самое важное что пока не выходит сделать - поменять биты местами местами, например, по схеме 1->2->3->14->1, т.е. первый бит переходит на второе место, второй на третье и т.д. Просто есть шаблон, который меняет первый и последний бит, но обмен битов происходит циклически в каждом байте, хотелось бы это изменить по схеме сверху. (Биты нумеруются от младшего к старшему, от 0 до 15 )
.model small
       ASSUME CS:kod, DS:dannyje, SS:stek
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
stek segment word stack 'STACK'
       dw 400h dup (00)               ; stek -> 2 Kb
stek ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dannyje segment para public 'DATA'
   
    soobshenije1:
       db 'Vvedi tekst do 80 simvolov'
 
    novajaStroka:   
       db 0Dh, 0Ah, '$'  ; tekst na ekrane
       
    buferVvoda:
       db 81, 00, 83 dup (0)  ; do 80 simvolov bez CR  
       
dannyje ends
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
LOCALS  @@
 
kod segment para public 'CODE'
    pecahtatjDvKodBajta proc near
       ; Sohranyajem ispolzujemyje registry v stek
       push        dx
       push        ax
       push        cx
       push        bx 
       ; CX - budet cikl po vsem 8 bitam bajta
       mov         cx, 0008
       mov dh,     al                                   ; sohranyajem al
       mov bl,     10000000b                            ; bl - v maske (filtre) dlia otbora nuzhnogo bita
 
       @@cikl_po_cx_ot_8:
       mov dl,     dh
       and dl,     bl                                   ; v registre dl teperj ostalsa odin interesujushij nas znachimyj bit
       dec cl                                           ; podgotavlivajem cl dlya drugoj operacii
       shr dl,     cl                                   ; interesujushij nas  dl  bit v registre stal mladshim
       shr bl,     1                                    ; maenyajem, chtoby sled raz on vybral drugoj bit iz bl
       inc cl                                           ; vosstanavlivajem cl  
       add dl,     '0'                                  ; teperj dl budet  '0' ili '1' -  ascii kody 0 ili 1
       mov ah,     02                                   ; ispolzujem vtoruju funkciju -  pechatj simvola na ekrane
       int 21h                                          ; funkcija DOS  
       loop  @@cikl_po_cx_ot_8                    ; povtoryajem poka CX>0
       
       ; Vosstanavlivajem registry:
       pop bx
       pop cx
       pop ax
       pop dx                
       ret
    pecahtatjDvKodBajta endp
;--------------------------------------------------------    
    pechatatjOtstup proc near
       ; Procedura pechatajet otstup
 
       push        dx
       push        ax
       mov dl,     ' '                                 ; dl <- prosto otstup
       mov ah,     02                                  ; vtoraja funkcija DOS
       int 21h
       pop ax
       pop dx                
       ret
    pechatatjOtstup endp
;-------------------------------------------------------
 
    nachalo:
 
       mov ax,     seg dannyje                   ; "zapuskajem" segment dannyh
       mov ds,     ax
       
       mov ah,     09                             ; nomer funkcii pechati
       mov dx,     offset soobshenije1             ; adres vyvodimogo teksta
       int 21h
 
       mov ah,     0Ah                            ; ifunkcija vvoda
       mov dx,     offset buferVvoda         ; bufer
       int 21h       
 
       mov ah,     09                             ; nomer funkcii pechati
       mov dx,     offset novajaStroka             ; adres vyvodimogo teksta
       int 21h
 
       ; Pechatajem dvoichnyje kody vvedennoj stroki:
     
       xor cx,     cx                              ; CX <- 0 
       mov cl,     byte ptr[buferVvoda + 1]   ; CX <- skolko bajtov, t.k. razmer bufera < 255   -> pomestitsa v CL
       mov bx,     2                               ; BX - sdvig ot nachala bufera vvoda, pervyj znachimyj bajt vtoroj
       
       @@cikl1_po_cx_ot_chisla_bajtov:     ; cikl po vvedennomu chislu bajtov (bez CR)
      
       mov al,     byte ptr[buferVvoda + bx]  ; "zapuskajem" vhodyashij bajt v AL
       call pecahtatjDvKodBajta                   ; pechatajem jego dvoichnyj kod
       call pechatatjOtstup                         ; otstup 
       
       ; Menyajem pervyj i poslednij bity (po zadaniju):
       mov ah,     al                              ; AH budem ispolzovatj dlia starshego bita
       mov dl,     al                              ; DL - dlia mladshego  
       and ah,     10000000b                       ; ostavlyajem tolko starshij bit
       and al,     11111110b                       ; obnuliajem mladshij bit AL 
       rol ah,     1                               ; ciklicheski smeshajem vlevo AH bajt: starshij bit stanet mladshim
       or  al,     ah                              ; pribavlyajem k  mladshemu bitu iz AL mladshij bit iz AH 
       and dl,     00000001b                       ; sotavlyajem tolko mladshij bit iz DL
       and al,     01111111b                       ; obnuliajem mladshij bit AL   
       ror dl,     1                               ; ciklicheski smeshyajem vpravo DL bajt: mladshij bit stanet starshim
       or  al,     dl                              ; pribavlyajem k starshemu bitu iz AL stasrhij bit iz DL
       mov byte ptr[buferVvoda + bx], al     ; sohranyajem izmennenyj AL v bufer
  
       inc bx                                     ; BX stanet pokazyvatj na drugoj bajt

       loop @@cikl1_po_cx_ot_chisla_bajtov   ; poka CX > 0
  
       mov ah,     09                             ; nomer funkcii pechati
       mov dx,     offset novajaStroka             ; adres vyvodimogo teksta
       int 21h

       ; Jeshio dolzhny otpechatatj izmenennuju stroku:
       ; kod pohozhij kak i v pervom sluchaje:
       xor cx,     cx
       mov cl,     byte ptr[buferVvoda + 1]   ; kiek baitu   
       mov bx,     2

       @@cikl2_po_cx_ot_chisla_bajtov:
      
       mov al,     byte ptr[buferVvoda + bx]
       call pecahtatjDvKodBajta   
       call pechatatjOtstup
    
       inc bx
 
       loop @@cikl2_po_cx_ot_chisla_bajtov

       ; Zavershajem programmu
       mov ah,     4ch                            ; nomer funkcii zavershenija
       int 21h
       
       mov ah, '?'
kod  ends
    end nachalo

Решение задачи: «Обмен битов местами по схеме 1->2->3->14->1»

textual
Листинг программы
mov ax,word ptr [sym] ;взять 2 символа
mov bx,ax       ;сделать копию
rol bx,2        ;13 бит старший ,0 бит 14-ый
rol ax,1        ;14 бит старший ,0 бит 15-ый
shld ax,bx,15       ;в AX вдвигать 15 бит из BX 
and bx,1        ;оставить только 0 бит без изменения остальные сбросить
or  ax,bx       ;вставить в результат

Объяснение кода листинга программы

  1. Задачей кода является обмен битов местами по схеме 1->2->3->14->1.
  2. В начале кода в регистр AX загружается значение из памяти по адресу, указанному в переменной sym, которая содержит два символа.
  3. Затем в регистр BX создаётся копия значения регистра AX.
  4. Далее, при помощи операции ROL, биты 13 и 0 регистра BX меняются местами, а при помощи операции ROL, биты 14 и 0 регистра AX меняются местами.
  5. При помощи операции SHLD, в регистр AX вдвигаются 15 бит из регистра BX.
  6. При помощи операции AND, в регистре BX оставляется только 0 бит без изменения, а все остальные сбрасываются.
  7. При помощи операции OR, содержимое регистра BX объединяется с содержимым регистра AX.

Оцени полезность:

7   голосов , оценка 4.143 из 5
Похожие ответы