Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Циклический сдвиг двойных слов 
V
    Опции темы
Vandalko
Дата 15.3.2009, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ести пример из методички по цикличному сдвигу двойных слов:

Код

mov edx,block
    xor esi,esi
    mov ecx,N-1; число подвійних слів
    lea ebx,block
m:        move eax,ebx+4[esi*4]
    shld ebx[esi*4],eax,10
    enc esi
    loop m
    shld ebx[esi*4],edx,10



Компилируется это горе(учитывая количество ошибок) только в таком виде:


Код

.386
.model small
ASSUME DS:DATA, CS:CODE 
DATA segment
block dd 0ABCDh, 0BCDEh, 0CDEFh, 0AAAAh, 0BBBBh, 0CCCCh, 0DDDDh
DATA ends
CODE segment
_run:  mov edx,block
    xor esi,esi
    mov ecx,6d; число подвійних слів
    lea ebx,block
shift:mov eax,4[esi*4]
    shrd [esi*4],eax,10
    inc esi
    loop shift
    shrd [esi*4],edx,10
CODE ends
end _run




Но проверка в отладчике показала на ошибку уже при первом проходе цикла... Но у меня есть подозрение smile что эта ошибка следствие изменения:

Код


            move eax,ebx+4[esi*4]
    shld ebx[esi*4],eax,10
    enc esi
    loop m
    shld ebx[esi*4],edx,10



на:

Код

            mov eax,4[esi*4]
    shrd [esi*4],eax,10
    inc esi
    loop shift
    shrd [esi*4],edx,10



Знатоки, подскажите, как выполнить циклический сдвиг двойных слов используя команду shrd  smile 
PM MAIL WWW ICQ   Вверх
Mikl_
Дата 16.3.2009, 12:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Vandalko, 
команда move eax,ebx+4[esi*4] на "правильном" ассемблере должна выглядеть так: mov eax,[ebx+esi*4+4]
а если принять во внимание команду lea ebx,block, то обе команды lea ebx,block и mov eax,[ebx+esi*4+4] 
можно заменить на одну mov eax,blok[esi*4+4]  smile ниже пример сдвига используя shrd
Код
;разделить операнд размером 64 бит на 16
.data
OP_L DD 0CDEFAAAAh    ;младшая часть операнда
OP_H DD 0ABCDBCDEh    ;старшая часть операнда
.code
MOV EDX,OP_L
SHL EDX,28; 32-4=28
MOV EAX,OP_H    ;сдвинуть 64-разрядный операнд циклически на 4 бита вправо. 
SHRD OP_L,EAX,4    ;Так как старшая часть операнда реально еще не сдвинулась, 
SHR OP_H,4    ;то нужно привести ее в соответствие с результатом
OR OP_H,EDX; добавляем 4 выдвинутых разряда из OP_L




Это сообщение отредактировал(а) Mikl_ - 16.3.2009, 14:30
PM MAIL   Вверх
Vandalko
Дата 16.3.2009, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



огромное спасибо за обьяснение, но что если нужно выполнить циклический сдвиг 121 раз ? тогда этот пример не подходит...
Давайте вернемся к моей реаизации - вот, программа после некоторых исправлений, но к сожалению программа вылетает с ошибкой...

Код

.386
.model small
ASSUME DS:DATA, CS:CODE 
DATA segment
block dd 0ABCDh, 0BCDEh, 0CDEFh, 0AAAAh, 0BBBBh, 0CCCCh, 0DDDDh
DATA ends
CODE segment
_run:  mov edx,block
    xor esi,esi
    mov ecx,6d; число подвійних слів
    lea ebx,block
shift:mov eax,[ebx+esi*4+4]
    shrd [ebx+esi*4],eax,10
    inc esi
    loop shift
    shrd [ebx+esi*4],edx,10
CODE ends
end _run


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


Опытный
**


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

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



Vandalko, 
Код
    mov ecx,6; число подвійних слів
    lea ebx,block
    mov edx,[ebx]    
shift:mov eax,[ebx+4]
    shrd [ebx],eax,10
    add ebx,4
    loop shift
    shrd [ebx],edx,10
Наверное так, но ведь отладчики никто не запрещал, возьми и посмотри под OllyDbg smile 

Это сообщение отредактировал(а) Mikl_ - 17.3.2009, 12:39
PM MAIL   Вверх
Vandalko
Дата 16.3.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



OllyDbg мне пока сложноват - учить надо smile
А вот Turbo Debugger самое оно...

Вобщем компилил-компилил я это чудо на 32битном masme и так ничего и не добился... Все решилось после компиляции на 16битном masm
Конечный вид програмы(если есть желание - просмотрите и скажите есть ли тут хоть доля правильности smile ):
Я ведь правильно понимаю, что 0000h-FFFFh это двойное слово ?
Код

.model small
.386
ASSUME DS:DATA, CS:CODE 
DATA segment
message db "Kilkist poslidovnux portiv: $"
block dd 1BCDh, 2CDEh, 3DEFh, 4AAAh, 5BBBh, 6CCCh, 7DDDh
DATA ends
CODE segment
run: mov ax,data
    mov ds,ax
    xor ax,ax
    mov edx,block
    xor esi,esi
    mov ecx,6d
    lea ebx,block
shift:mov eax,[ebx+esi*4+4]
    shrd [ebx+esi*4],eax,121
    inc esi
    loop shift
    shrd [ebx+esi*4],edx,121
    xor eax,eax
    mov ah,09h
    lea dx,message
    int 21h
    xor eax,eax
    int 11h
    xor edx,edx
    mov dl,ah
    shl dl,4
    xor eax,eax
    mov al,dl
    shr al,4
   mov dl,al
    xor eax,eax
    mov ah,2
    int 21h

    xor eax,eax
    mov ax,4c00h
    int 21h
CODE ends
end run


Во всяком случае спасибо за советы  smile 


Програма дополнилась новым заданием - вывести информацию о количестве последовательных портов... Добыть саму информацию было несложно, но вот как теперь вывести ее на экран ? Обратите внимание на выделеный  участок кода. По идее он должен бы вывести число, но... ничего так и не выводит....  smile 

Это сообщение отредактировал(а) Vandalko - 16.3.2009, 17:51
PM MAIL WWW ICQ   Вверх
Mikl_
Дата 17.3.2009, 05:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Vandalko, 
1) не плохо свои листинги снабжать комментариями, если ты DOS только изучаешь, то я за 20 лет его забыл окончательно. Да и в практическом программировании DOS не применяется
2) если вврху листинга нет директивы .radix 2 или .radix 8 или .radix 16, то снабжать десятичные цифры спецификатором d как в этой команде mov ecx,6d не нужно -- это только вводит в заблуждение, другое дело если у тебя установлено .radix 16, тогда 6Dh=109
3) это что за бред shrd [ebx+esi*4],eax,121 32-разрядный регистр или ячейку памяти больше чем на 32 бита не сдвинуть -- разрядов не хватает!
4) не правильно, число в диапазоне от 0000h до 0FFFFh (от 0 до 65535) это слово, двойное слово это число в диапазоне от 00000000h до 0FFFFFFFFh (от 0 до 4294967295)
5) прерывание 11h - получить список оборудования; возвращает в регистре AX список оборудования BIOS; в регистре AX в 9-11 разрядах число установленных последовательных портов
Код
DATA segment
message db "В компьютере "
message1 db "0 последовательных портов$"
DATA ends
CODE segment
run: mov ax,data
    mov ds,ax
int 11h
shr al,4; удаляем с 12 по 15 разряды
and al,111b; удаляем ненужный 8 разряд -- оставляем только разряды 9-11
or message1,al;  помещаем реальное число вместо символа "0"
mov ah,09h
    mov dx,offset message
    int 21h; выводим сообщение на экран



Это сообщение отредактировал(а) Mikl_ - 17.3.2009, 07:16
PM MAIL   Вверх
Vandalko
Дата 17.3.2009, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



спасибо за комментарии...

shrd [ebx+esi*4],eax,121 - ну, нужно ведь выполнить циклический сдвиг на 121 бит... этот вариант скомпилился и я его оставил  smile Если есть идеи как это выполнить - я буду только рад их рассмотреть smile

Теперь вопрос по отладчику - скажем мне нужно переслать какието данные в сегмент кода, как это можно увидеть в отладчике ? Я имею ввиду не факт пересылки а присутствие этих данных (если конечно такое возможно, ибо mov cs:0100,temp компилится, но каких то изменений в отладчике не наблюдается - хотя, учитывая мой опыт работы с ASM скорее всего я просто незнаю как их увидить)?

По поводу вывода количества последовательных портов, то код в предыдущим варианте был не конечным вариантом - я потом доделал и все нормально работало, но во всяком случае спасибо за Ваш алгоритм - он будет третьим  smile 

P.S.  smile по поводу DOS программирования, то возможно я никогда и не взялся бы за ASM если бы не программа в институте ибо мне больше по душе Java, хотя именно изучение ассемблера дает более глубокое понимание работы компьютера и работы программы в целом...

P.S.2. Мальчик я, мальчик...  smile 

Это сообщение отредактировал(а) Vandalko - 23.3.2009, 23:31
PM MAIL WWW ICQ   Вверх
Mikl_
Дата 18.3.2009, 06:31 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Vandalko)
этот вариант скомпилился и я его оставил   Если есть идеи как это выполнить - я буду только рад их рассмотреть
Думать головой нужно прежде, чем начинаешь компилировать -- компьютер безропотно согласится дать себя сжечь, но это же не повод так с ним поступать  smile -- если тебе требуется циклически сдвинуть массив dd 0ABCDh, 0BCDEh, 0CDEFh, 0AAAAh, 0BBBBh, 0CCCCh, 0DDDDh на 121 бит, то берешь карандашь и начинаешь считать -- в твоем массиве 7 32-битовых переменных 7*32=224 бита, каждый раз при сдвиге на 32 разряда переменная 0ABCD с номером 0 попадет на место переменной 0DDDDh с номером 6, которая попадет на место переменной с номером 5 и так далее; 121/32=3 и 25 в остатке -- таким образом тебе сперва необходимо передвинуть по кругу все твои переменные на три позиции используя команду movsd до состояния dd 0AAAAh, 0BBBBh, 0CCCCh, 0DDDDh, 0ABCDh, 0BCDEh, 0CDEFh а затем осуществить сдвиг на оставшиеся 25 разрядов shrd [ebx+esi*4],eax,25  наверное как-то так smile 
Ну или как вариант, сдвигаем на четыре переменные вправо, а потом 32-25=7 осужествляем циклический сдвиг влево на 7 бит иначе если ты сдвигаешь вправо или влево на 32 или больше разрядов в твой переменной будут нули во всех разрядах! smile 

Это сообщение отредактировал(а) Mikl_ - 19.3.2009, 09:08
PM MAIL   Вверх
Mikl_
Дата 19.3.2009, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Vandalko,  smile Вы мальчик или девочка?  smile  В профиле пишете пол мужской, а в сообщении
Цитата(Vandalko)

поводу DOS программирования, то возможно я никогда и не взялася бы за ASM 
 user posted image

Это сообщение отредактировал(а) Mikl_ - 19.3.2009, 12:37
PM MAIL   Вверх
YDI
Дата 14.4.2009, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ув. товарищи, почти эта же прога, при компиляции выдает ошибку "деление на ноль". Укажите где промах.
Код

.model tiny
.386
ASSUME DS:DATA, CS:CODE 
DATA segment use16
res db ?
message db "Kolichestvo portov:$"
block dd 1ACDh, 2BDEh, 3CEFh, 4AAAh, 5BBBh, 6CCCh, 7DDDh
DATA ends
CODE segment
run:    
mov ax,data
    mov ds,ax
    mov edx,block
    xor esi,esi
    mov ecx,6
    lea ebx,block
shift:  mov eax,[ebx+esi*4+4]
    shrd [ebx+esi*4],eax,30
    inc esi
    loop shift
    shrd [ebx+esi*4],edx,30
    mov ah,09h
    lea dx,message
    int 21h
        xor eax,eax
    int 11h 
    xor edx,edx
    mov dl,ah
    shl dl,4
    xor eax,eax
    mov al,dl
    shr al,5
    mov dl,al
    mov res,dl
    mov ah,02h
    add dl,30h
    int 21h
CODE ends
end run




Это сообщение отредактировал(а) YDI - 14.4.2009, 01:49
PM MAIL   Вверх
Mikl_
Дата 14.4.2009, 03:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



YDI, 
.model tiny  подразумевает создание COM-файла, у которого сегмент кода, стека и данных сосредоточены "в одном флаконе" (в одном сегменте  smile ) стало быть строки mov ax,data/mov ds,ax здесь не нужны, но зато у тебя отсутствует строка "ORG 100h" с которой должны начинаться COM-файлы. Так же нет команд, которые должны завершать твою программу "RET" или "int 20h" для COM-файлов или "mov ax,4C00h/int 21h" для EXE-файлов, после которых управление должно передаться операционной системе DOS или Windows -- так как твоя программа на самом деле не заканчивается командами " mov ah,02h/ add dl,30h/ int 21h" ее поведение не предсказуемо, хорошо, что она где-то, что-то разделила на ноль и на этом прервалась -- будь внимательней!  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm для начинающих"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

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

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


 




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


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

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