Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ассемблерная процедура. 
:(
    Опции темы
1VITOLD1
Дата 23.12.2008, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.12.2008

Репутация: нет
Всего: нет



Помогите сделать процедуру SHR1(var M1;len,count: word), где М1-большое целое положительное число (байтовый масив длинной len), count - количество розрядов сдвига. Которая реализовала бы операцыю линейного сдвига вправо на количество двоичных розрядов, что задана параметром count .При этом теряеться count младшых розрядов, а в count  старшых розрядов заноситься 0. При роботе должны использоваться команды для 32-розрядных даных. Если значение len не кратно 4, то при необходимости для последних байт использовать команды для 8-розрядных даных.
Заранее благодарен )


 

    

Это сообщение отредактировал(а) 1VITOLD1 - 24.12.2008, 10:32
PM MAIL   Вверх
Mikl_
Дата 24.12.2008, 05:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 8
Всего: 14



1VITOLD1, Для получения ответа обязательно укажи название своего ВУЗа и факультета -- это мне необходимо для статистики
судя по оформлению процедуры SHR1(var M1;len,count: word), это должна быть процедура для Паскаля с ассемблерной вставкой или это "чистый" ассемблер? Если целиком на ассемблере, то на каком MASM, TASM, NASM, YASM, A86? Не пойму "зсув" это по-белорусски "сдвиг"?
PM MAIL   Вверх
1VITOLD1
Дата 24.12.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.12.2008

Репутация: нет
Всего: нет



Здесь процедура для Паскаля с ассемблерной вставкой ...Используем транслятор MASM..

ВДТУ факультет информатики..


заранее спасибо за помощь.

Это сообщение отредактировал(а) 1VITOLD1 - 24.12.2008, 10:55
PM MAIL   Вверх
Mikl_
Дата 25.12.2008, 04:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 8
Всего: 14



1VITOLD1
Код
program abc;
const n=255;
type mas=array [1..n] of byte
label a0,a1,a2;
{процедура SHR1(var M1;len,count: word), где М1-большое целое положительное число (байтовый масив длинной len), 
count - количество разрядов сдвига. Которая реализует операцию линейного сдвига вправо на количество двоичных 
разрядов, что задана параметром count .При этом теряется count младших разрядов, а в count  старших разрядов 
заноситься 0. При работе должны использоваться команды для 32-разрядных даных. Если значение len не кратно 4, 
то при необходимости для последних байт использовать команды для 8-разрядных даных.}
procedure SHR1(M1:mas; len,count: word);
begin {начало процедуры}
asm {начало ассемблерной вставки}      
      movzx ecx,count    {ecx:=count }
a0: lea esi,M1{позиционирую регистр на начало массива}
       movzx ebx,len
       mov edx,ebx
       and ebx,0FFFFFFFCh {ebx:=(len/4)*4       в ebx число кратное 4}
       and edx,3 {edx:=len mod 4                       в edx остаток от деления на 4}
       clc {CF=0}
       test edx,edx {если len кратно 4 перейдем на метку a2}
       jz a2
a1: rcr byte ptr [esi],1 {сдвигаем вправо по одному байту}
       inc esi
       dec edx
       jnz a1
a2: rcr dword ptr [esi],1 {сдвигаем вправо по четыре байта}
       add esi,4
       sub ebx,4
       jnz a2
       loop a0
end;{конец ассемблерной вставки}
end;{конец процедуры}
begin {начало программы}
...
SHR1(x,y,z); {вызываем процедуру внутри тела программы}
...
end. {конец программы}


Это сообщение отредактировал(а) Mikl_ - 25.12.2008, 13:38
PM MAIL   Вверх
1VITOLD1
Дата 26.12.2008, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.12.2008

Репутация: нет
Всего: нет



Mikl_, Спасибо большое..

а вот не подскажите как можно переделать процедуру,(делает сдвиг влево ) под анологичную..но что бы сдвигала число вправо

вот есть КОД процедуры со сдвигом влево
Код

.386


BigShlCount proc         far
        public       BigShlCount
; procedure BigShlCount(var mas,len,count:word)
; mas - адреса байтового масиву
@mas         equ         [bp+10]; адреса адреси 
; len - кiлькiсть байт масива, якi необхiдно вивести на екран
@len         equ         [bp+8]; адреса кiлькостi
; count - кiлькiсть бiт зсуву
@count       equ         [bp+6]; адреса кiлькостi
;
;
        push    bp
        mov     bp,sp        ; базова адреса фактичних параметрiв


; ax - кол-во итераций (по 4 байта)
; ebx - данные
; cx - величина сдвига (меньше 8)
; edx - перенос
; si - адрес откуда считываем
; di - адрес куда пишем


    mov    dx, @count
    mov    cx, dx
    shr    dx, 3 ;count/8
    and    cx, 0111b ;count mod 8
        
    lds    si, @mas ;грузим сегмент в ds, а смещение в si

    mov    bx, @len
    mov    di, bx ;di = len
    dec    di ; len - 1
    add    di, si ; адрес последнего элемента в массиве
    sub    bx, dx ;bx = len - count/8
    jle    @bsc3  ;такой большой сдвиг, что результат будет 0. Сразу на обнуление.
    mov    ax, bx ;ax = len - count/8
    dec    bx     ;bx = len - count/8 - 1  (номер последнего элемента, который надо сдвигать)
    shr    ax, 2  ;ax = (len - count/8) / 4 (кол-во 4-байтных кусков)

    xor    edx, edx ;тут будет храниться перенос
    add    si, bx ;адрес последнего элемента, который надо сдвигать
    or    ax, ax ;ничего не дедаем, но выставляем флаги
    jz    @bsc1_new
    sub    si, 3 ;начало последних 4-х байт для считывания
    sub    di, 3 ;начало последних 4-х байт для записи
    
    mov    ebx, [si] ; читаем последние 4 байта для сдвига
    shl    ebx, cl      ; сдвиг
    mov    [di], ebx ; запись
        
    dec    ax      ; одни 4 байта уже отработали
    jz    @bsc0      ; если группы по 4 байта закончились
@bsc2:
    sub    si, 4      ; переходим на следующие 4 байта
    sub    di, 4      ; переходим на следующие 4 байта
    mov    ebx, [si] ; читаем 4 байта
    mov    edx, ebx  
; тут ebx = edx = sssxxxxx, где s - это те данные, которые нам надо выделить как перенос, 
; а x - это мусор
    shl    ebx, cl   ; ebx = xxxxx000
    mov    [di], ebx ; записали
    shr    ebx, cl   ; ebx = 000xxxxx, edx = sssxxxxx
    sub    edx, ebx  ; edx = sss00000
    rol    edx, cl   ; edx = 00000sss (циклич. сдвиг)
    add    [di+4], edx ; прибавили перенос к предыдущему

    dec    ax    ;и так ax раз
    jnz    @bsc2

@bsc0:
    dec    si ;теперь указывает на незавершенный байт
    dec    di ;теперь указывает на незавершенный байт

@bsc1:  
    mov    ax, @mas
    cmp    si, ax ;сколько осталось?
    jl    @bsc3  ; всё готово
    jz    @bsc4  ; еще один байт
    ;больше одного (2 или 3). Скопируем сначала 2 байта
    dec    si ;теперь указывает на 2 байта
    dec    di ;теперь указывает на 2 байта
    mov    bx, [si] ;читаем 2 байта

    mov    dx, bx  
; тут ebx = edx = sssxxxxx, где s - это те данные, которые нам надо выделить как перенос, 
; а x - это мусор
    shl    bx, cl   ; bx = xxxxx000
    mov    [di], bx ; записали
; !!!! был ли предыдущий??
    shr    bx, cl   ; bx = 000xxxxx, dx = sssxxxxx
    sub    dx, bx   ; dx = sss00000
    rol    dx, cl   ; dx = 00000sss (циклич. сдвиг)
    add    [di+2], dx ; прибавили перенос к предыдущему

    dec    si
    dec    di
    cmp    si, ax ;если равны, то надо еще один байт. Иначе все.
    jnz    @bsc3

@bsc4: ;надо скопировать 1 байт
    mov    bl, [si] ;читаем байт
    mov    dl, bl
; тут ebx = edx = sssxxxxx, где s - это те данные, которые нам надо выделить как перенос, 
; а x - это мусор
    shl    bl, cl   ; bl = xxxxx000
    mov    [di], bl ; записали
; !!!! был ли предыдущий??
    shr    bl, cl   ; bl = 000xxxxx, dl = sssxxxxx
    sub    dl, bl   ; dl = sss00000
    rol    dl, cl   ; dl = 00000sss (циклич. сдвиг)
    add    [di+1], dl ; прибавили перенос к предыдущему
    dec    di
    jmp    @bsc3


;то же самое, только для ПЕРВЫХ БАЙТ массива. (не надо прибавлять перенос к предыдущему)
@bsc1_new:
    mov    ax, @mas
    cmp    si, ax ;сколько осталось?
    jl    @bsc3  ; всё готово
    jz    @bsc4_new  ; еще один байт
    ;больше одного (2 или 3). Скопируем сначала 2 байта
    dec    si ;теперь указывает на 2 байта
    dec    di ;теперь указывает на 2 байта
    mov    bx, [si] ;читаем 2 байта

    mov    dx, bx  
    shl    bx, cl   ; bx = xxxxx000
    mov    [di], bx ; записали

    dec    si
    dec    di
    cmp    si, ax ;если равны, то надо еще один байт. Иначе все.
    jnz    @bsc3

    jmp    @bsc4
@bsc4_new: ;надо скопировать 1 байт
    mov    bl, [si] ;читаем байт
    mov    dl, bl
    shl    bl, cl   ; bl = xxxxx000
    mov    [di], bl ; записали
    dec    di


@bsc3: ;заполняем нулями остаток
;di - это первый элемент, который надо обнулить. Если массив еще не закончился.
    xor    edx, edx

    mov    ax, @mas
    mov    cx, di
    inc    cx
    sub    cx,ax ;cx = кол-во элементов для обнуления
    mov    ax,cx ;ax = кол-во элементов для обнуления

    shr    cx, 2 ;cx = кол-во/4
    jz    @bsc6 ; кол-во/4 = 0
    inc    di    ; элемент перед началом первых 4-х байт для обнуления
@bsc5:
    sub    di, 4 ;следующие 4 байта
    mov    [di], edx ;обнуляем
    loop    @bsc5 ;цикл

    dec    di ;байт для обнуления
@bsc6:    
    and    ax, 011b ;кол-во mod 4
    jz    @bscExit ; если все обнулили, то выходим
@bsc7:
    mov    [di],dl
    dec    di ;байт для обнуления
    dec    ax
    jnz    @bsc7 ; цикл

@bscExit:
        pop     bp
        ret     8
BigShlCount endp
_text   ends
        end     

                   

во..  
заранее СПАСИБО..


PM MAIL   Вверх
Mikl_
Дата 27.12.2008, 05:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 8
Всего: 14



1VITOLD1, в двух словах -- меняешь rol на ror и двигаешься не от конца массива, а от его начала и, соответственно, меняешь dec si, dec di на inc si, inc di 
для сдвига сразу 8 байт под .386 можно использовать shrd / shld 
Код
;разделить операнд размером 64 бит на 16=2 в 4 степени
.data
OP dq 1234567890ABCDEFh    ;64-разрядный операнд
.code
MOV EAX,dword ptr [OP+4];в EAX старшую часть операнда OP      
SHRD dword ptr OP,EAX,4;сдвигаем младшую часть операнда вправо, 4 освободившиеся разряда
;заменяют выдвинувшиеся 4 разряда из EAX, при этом содержимое в EAX не изменяется
;так как старшая часть операнда реально еще не сдвинулась, 
SHR dword ptr [OP+4],4;то нужно привести ее в соответствие с результатом
; при использовании SHLD в регистр отправляешь младшую часть операнда
 user posted imageРасшифруй пожалуйста, что такое ВДТУ?

Это сообщение отредактировал(а) Mikl_ - 27.12.2008, 08:43
PM MAIL   Вверх
1VITOLD1
Дата 27.12.2008, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.12.2008

Репутация: нет
Всего: нет



Mikl_, Винницкий государственный технический университет  
..я понимаю что с начала надо двигаться.....Но не получаеться.. коректно реализовать что бы указатель был вначале и исполнялись переходы( 
PM MAIL   Вверх
Mikl_
Дата 29.12.2008, 10:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 8
Всего: 14



1VITOLD1, А мой-то вариант чем был плох? он и короче и понятнее  smile 
Цитата(1VITOLD1)
реализовать что бы указатель был вначале

 lds    si, @mas ;грузим сегмент в ds, а смещение в si<-- si указывает на начало массива
    mov    bx, @len <-- в  bx длину массива
    mov    di, bx ;di = len
    dec    di ; len - 1
    add    di, si ; адрес последнего элемента в массиве <-- di указывает на предпоследний элемент массива
тебе нужно просто mov di,si <-- di указывает на начало массива
и везде где у тебя dec di пиши inc di а вместо sub di,4 ;следующие 4 байта пишешь add di,4  smile 

    
PM MAIL   Вверх
1VITOLD1
Дата 29.12.2008, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 23.12.2008

Репутация: нет
Всего: нет



Спасибо...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm для начинающих | Следующая тема »


 




[ Время генерации скрипта: 0.1037 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.