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