Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Assembler

Автор: bomzzz
Дата сообщения: 22.08.2012 21:57
у тебя запутано пояснено. возможно так, а возможно это элемент таблицы A7 - селектор или дескриптор не помню точно как там

Добавлено:

Цитата:
При адресации памяти в защищённом режиме команды ссылаются на сегменты, указывая не их адреса (как в режиме реальных адресов), а описания сегментов (их дескрипторы). Указатель на описание сегмента называется селектор. Другими словами, селектор - это номер дескриптора из таблицы дескрипторов.
Адресация производится через пару регистров сегмент:смещение, причём, в качестве сегментного регистра используются обычные CS, SS, DS, ES, FS и GS (последние два появились в 386-м процессоре), но в них указывается не адрес сегмента, а селектор дескриптора.
Автор: MERCURY127
Дата сообщения: 22.08.2012 22:11
pavel1978, правильно
bomzzz, это же чистый ДОС, МКБ, защищенный режим управляется другими епархиями и тут совершенно ни к чему
Автор: bomzzz
Дата сообщения: 22.08.2012 22:18

Цитата:
1. таблицы таблиц (list of list, или сокр-но lol) и

а о каких таблицах речь идет? прерываний что ли?
Автор: MERCURY127
Дата сообщения: 22.08.2012 22:42
Нет конечно
Автор: pavel1978
Дата сообщения: 22.08.2012 23:25

Цитата:
pavel1978, правильно


Это радует. Согласно приведенной Вами ссылке, "следующий Блок Управления Памятью (МСВ) = текущий + размер +1" Текущий = А96h, а как вычислить размер его (длину), этого А96? Есть формула? Ведь любая программа, которая нам бы размер сей показала, тоже основывается на математической логике, так?

Добавлено:
Уточню - размер чего прибавлять?
Автор: MERCURY127
Дата сообщения: 22.08.2012 23:44
Во 1х, все блоки выравнены на границу 16 байт (=параграф), потому тебе достаточно оперировать сегментами.
Во 2х, сам МКБ занимает 1 параграф. Плюс расположенный за ним собственно блок памяти, размер которого, в параграфах, и задан в МКБ.
Отсюда следует: берем в ЛоЛ сегмент 1ого (корневого) МКБ (0х1234), и далее в цикле 1) проверяем 1й байт МКБ (0х1234:0), если =0х5А, то конец, иначе если =0х4Д, то шаг 2, иначе глюк. 2) считываем длину блока памяти (0х2345). 3) вычисляем новый адрес (сегмент следующего МКБ) =0х1234 0х2345 1 (текущий МКБ - 1 параграф) = 0х357А. Далее обратно к шагу 1) с новым адресом. Это называется связный список, когда каждый элемент указывает на следующий. Понятно?
Мне пора, до завтра.
Автор: MihaNix
Дата сообщения: 22.08.2012 23:45
Это если com файл полученный под DOS запускать.
Ну а под виндами современными - ничего не произойдет страшного.
Ну а по заданию - программу вообще в debuger в режиме трассировке показать надо было, чтобы препод заценила...

А в hiew как такую конструкцию записать?

в debuger - поддерживает такой синтаксис: mov byte ptr [0], al
а вот так кушать не хочет: mov byte ptr x[0], al
Автор: MERCURY127
Дата сообщения: 22.08.2012 23:51
MihaNix, мой вариант был для нормального, культурного ассемблера, типа МАСМ/ТАСМ. А в Хиев конечно можно много чего из дикорастущей живности сочинить. Можно завтра, а?
Автор: akaGM
Дата сообщения: 23.08.2012 00:30
пардон, что-то я с ответом припозднился...
Автор: pavel1978
Дата сообщения: 23.08.2012 08:33

Цитата:
Во 2х, сам МКБ занимает 1 параграф. Плюс расположенный за ним собственно блок памяти, размер которого, в параграфах, и задан в МКБ.
Отсюда следует: берем в ЛоЛ сегмент 1ого (корневого) МКБ (0х1234), и далее в цикле 1) проверяем 1й байт МКБ (0х1234:0),  если =0х5А, то конец, иначе если =0х4Д, то шаг 2, иначе глюк. 2) считываем длину блока памяти (0х2345). 3) вычисляем новый адрес (сегмент следующего МКБ) =0х1234  0х2345  1 (текущий МКБ - 1 параграф) = 0х357А. Далее обратно к шагу 1) с новым адресом.


Сколько "весит" параграф? Мне какой размер добавлять-то?! (А96+16+1)h что ли? Мне не надо прогу писать, мне просчитать блоки памяти надо в контрольной...
Автор: bomzzz
Дата сообщения: 23.08.2012 12:36
16 байт
Автор: Maria93
Дата сообщения: 25.08.2012 11:49
Написать программу, которая скопирует 32-битную переменную А в переменную В, поменяв байты местами. Например для A=1A2B3C4D программа возвращает В=4D3C2B1A.

DS1 SEGMENT

A: D 1A1B3C4D
B DD DUP(?)
DS1 Ends
SS1 SEGMENT
DW 100h DUP(?)
SS1 Ends
CS1 Segment
Assume: DS:DS1, SS:SS1, CS:CS1
START: MOV Ax, DS1
MOV DS, Ax

;следующие 6 строк меняют последовательность байтов в А
MOV Bx, A[SI]
MOV A[SI], A[SI+3]
MOV A[SI+3], Bx
MOV Bx, A[SI+1]
MOV A[SI+1], A[SI+2]
MOV A[SI+2], A[SI+1]

;следующие 7 строк копируют А в В
MOV Cx, Na
MOV SI, O
L1: MOV Dx, A[SI]
MOV B[SI], DX
INC SI INC SI
DEC CX
JNZ L1

MOV AH, 4Ch
INT 21h
CS1 Ends
End start
Автор: bomzzz
Дата сообщения: 25.08.2012 11:51
а специальные команды переставляющие байты нельзя использовать?
правда я их с ходу не вспомню. не доводилось использовать
ну или хотя бы ROL уже будет проще, но эти команды по такту на смещение используют - неэкономно получится

BSWAP


Цитата:

mov eax, dword ptr [value]
bswap eax
mov dword ptr [value], eax



Цитата:
.686

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data
mestitle    db "Bomz",0
form        db "EAX: %x", 0
value        dd 1A2B3C4Dh

.data?
buffer        db 512 dup(?)

.code
start:
    mov    eax, dword ptr [value]
    bswap    eax
    mov    dword ptr [value], eax
    invoke    wsprintf,ADDR buffer,ADDR form,eax
    invoke    MessageBox,0,ADDR buffer,ADDR mestitle,MB_ICONASTERISK
    invoke    ExitProcess,0
end start




работкаит

Добавлено:

Цитата:
.486

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data
mestitle    db "BSWAP",0
form        db "EAX: %x",13,10,"EBX: %x", 0
value        dd 1A2B3C4Dh

.data?
buffer        db 64 dup(?)

.code
start:
    mov    ebx, dword ptr [value]
    mov    eax, ebx
    bswap    ebx
    mov    dword ptr [value], ebx
    invoke    wsprintf,addr buffer,addr form,eax,ebx
    invoke    MessageBox,0,addr buffer,addr mestitle,MB_ICONASTERISK
    invoke    ExitProcess,0
end start




http://rghost.ru/39992136

486 процессор уже BSWAP поддерживал

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

Добавлено:
вот с rol

Цитата:
.386

.model flat, stdcall
option casemap :none

include \MASM32\INCLUDE\windows.inc
include \MASM32\INCLUDE\user32.inc
include \MASM32\INCLUDE\kernel32.inc
includelib \MASM32\LIB\user32.lib
includelib \MASM32\LIB\kernel32.lib

.data
mestitle    db "ROL",0
form        db "EAX: %x",13,10,"EBX: %x", 0
value        dd 1A2B3C4Dh

.data?
buffer        db 64 dup(?)

.code
start:
    mov    ebx, dword ptr [value]
    mov    eax, ebx

    rol bx, 8
    rol ebx, 16
    rol bx, 8

    mov    dword ptr [value], ebx
    invoke    wsprintf,addr buffer,addr form,eax,ebx
    invoke    MessageBox,0,addr buffer,addr mestitle,MB_ICONASTERISK
    invoke    ExitProcess,0
end start


Добавлено:
а если препод будет возбухать скажи, что на это надо давать задачу на сортировку массива или быструю сортировку строк, а в этой задачи учащиеся ознакомились с командами ROL и SWAP в чем гораздо больше пользы, чем учиться неоптимально тупорыло задачи поставленные решать
Автор: bomzzz
Дата сообщения: 25.08.2012 13:57
BSWAP занимает около 4 условных тактов, а вариант с ROL около 12
Автор: ne_viens
Дата сообщения: 26.08.2012 00:46
Вопрос про условное ассемблирование на Xcode.
По описанию единственный способ собрать отдельно 32бит от 64бит можно только при помощи .if, .else, .endif комбинации.

Код:
.text
.globl _sw1

_sw1:
.if x86_64
movl $64, %edx
L1:
rolq %rdi
rcrq %rax
decl %edx
jg L1
    
ret

.else
pushl %esi
movl 8(%esp), %esi
pushl %edi
movl 16(%esp), %edi
movl $32, %ecx
L0:
roll %edi
rcrl %eax
roll %esi
rcrl %edx
decl %ecx
jg L0

popl %edi
popl %esi
ret

.endif
Автор: bomzzz
Дата сообщения: 26.08.2012 13:01
еще такой способ придумкал

Цитата:
xchg bl, bh
rol ebx, 16
xchg bl, bh

но он не быстрее почему то, по крайней мере на пентиуме 4 нортвуд

и еще вот такой. но он тоже не оптимальный

Цитата:
    mov    ecx, dword ptr [value]

    mov    bx, word ptr [value]
    mov    ax, word ptr [value+2]
    xchg bl, bh
    xchg al, ah
    mov    word ptr [value], ax
    mov    word ptr [value+2], bx

    mov    edx, dword ptr [value]

    invoke    wsprintf,addr buffer,addr form,ecx,edx
Автор: bomzzz
Дата сообщения: 27.08.2012 10:15
никто не может на пальцах работу prefetchnta объяснить? чета не могу нагуглить никакого простого описания
Автор: MERCURY127
Дата сообщения: 28.08.2012 17:18
bomzzz, оно тебе реально надо??? на пальцах это не объясняется...
http://forum.ixbt.com/topic.cgi?id=8:20266-4
http://www.cyberforum.ru/assembler/thread452084.html
http://www.wasm.ru/forum/viewtopic.php?pid=55381
http://lib.profi.net.ua/izone/release32/pub/pentium.htm

Цитата:
Для предварительного считывания областей памяти в кэш предназначены команды prefetcht0 (одновременное считывание в кэш первого и второго уровней), prefetcht1 и prefetcht2 (считывание только в кэш второго уровня), а также prefetchnta (считывание сразу в кэш первого уровня, минуя второй). Инструкция sfetch осуществляет принудительную синхронизацию данных в кэше и оперативной памяти. Это стоит сделать перед обработкой потенциально опасных фрагментов кода, которые могут вызвать уничтожение накопленных в кэше данных до того, как они попадут в оперативную память.

оно реально надо??? это ПРИВИЛЕГИРОВАННЫЕ команды...
Автор: bomzzz
Дата сообщения: 28.08.2012 17:35
конечно надо. чтоб кешем управлять научится
Автор: MERCURY127
Дата сообщения: 28.08.2012 17:54
конечно... процессор ведь тупой и не знает, что ему в следующем такте понадобится...
Автор: bomzzz
Дата сообщения: 28.08.2012 17:56
у процессора и так забот полно, он по тридцать процессов и бог знает сколько потоков обслуживает. тут никакого кеша не напасешься.
Автор: MERCURY127
Дата сообщения: 28.08.2012 18:02
вот именно... а тут еще и ты со своими указаниями спешишь помочь как Чип и Дейл... бедный процессор...
Автор: bomzzz
Дата сообщения: 28.08.2012 18:03
если я из 512 кбайт, забью 128 байт процессор не обидится

Добавлено:

Цитата:
Предварительная загрузка(Prefetching)

Следующая оптимизация более тонкая. В добавление к SIMD инструкциям, SSE предоставляет инструкции, которые дают вам возможность управления обменом данными с кэшем. Intel SSE учебник предоставляет полное описание этих инструкций, но нас сейчас интересует только одна - prefetchnta инструкция. Она позволяет загружать(pre-load) адрес в специальную не временную(non-temporal) область L1 кэша, которая гарантирует, не заменять любые данные, загруженные в кэш. Мы используем prefetchnta чтобы указать, что нам нужно загрузить данные по определенному адресу в кэш, по которому можно читать (или писать).

Именно так нам и надо обращаться с потоками входных и выходных векторов - нам надо, чтобы вектор находился в кэше пока мы читаем из него (или замписываем). После нам надо, чтобы его НЕ БЫЛО, поэтому у нас есть много пространства в кэше для остальных векторов. Вставим пару prefetchnta инструкций в BatchMultiply - одна для входного потока, и вторая - для выходного:
// BatchMultiply4 -- Модификация BatchMultiply3, использующая
// SSE prefetching инструкции для ускорения обработки больших
// наборов входных данных.
//
// Выполнение: 21 цикл/вектор
void BatchMultiply4(Matrix4f &m, Vector4f *vin, Vector4f *vout, int len)
{
    // транспонировать матрицу в xmm4-7
    m.TransposeIntoXMM();
    static const int vecSize = sizeof(Vector4f);

    __asm {
        mov            esi, vin
        mov            edi, vout
        mov            ecx, len

BM4_START:
        // загрузить следуюший входной вктор в xmm0, и передвинуть
        // входной указатель . Загрузить остальные(upcoming) векторы
        // в кэш.
        movaps    xmm0, [esi]
        prefetchnta    [esi+0x30]

        // записать y в xmm1, z в xmm2, и w в xmm3 (оставляя
        // x в xmm0).
        movaps    xmm1, xmm0
        add            esi, vecSize
        movaps    xmm2, xmm0
        add            edi, vecSize
        movaps    xmm3, xmm0
        prefetchnta [edi+0x30]
        shufps    xmm0, xmm0, 0x00
        shufps    xmm1, xmm1, 0x55
        shufps    xmm2, xmm2, 0xAA
        shufps    xmm3, xmm3, 0xFF
        
        // умножить xmm0-3 на соответствующие столбцы матрицы
        // (hiding a pointer increment between the multiplies)
        mulps        xmm0, xmm4
        mulps        xmm1, xmm5
        mulps        xmm2, xmm6
        mulps        xmm3, xmm7

        // суммировать результаты в xmm1
        addps        xmm1, xmm0
        addps        xmm2, xmm3
        addps        xmm1, xmm2

        // записать результаты в vout и продолжить
        // выполнение цикла
        movaps    [edi-0x10], xmm1
        dec            ecx
        jnz            BM4_START
    }
}

Во-первых, выгода от использования загрузки в кэш не сильно видна - мы сэкономили всго один цикл! Но, как только мы начнем использовать большие потоки векторов (примерно 10000), эта версия функции будет работать заметно быстрее, чем предыдущая.

Можете поэкспериментировать, чтобы найти подходящее значние смещения prefetching'а, которое будет наилучшим для вашего приложения (для Pentium 3 48 байт подходит лучше всего). Еще может быть полезным использование movntps инструкции, используемой для записи содержимого SSE регистров напрямую в память минуя кэш (т.о. избегая загрязнения кэша). Более полезную информацию смотрите в учебнике Intel.

Чтобы увидеть результат использования prefetching'а, запустите simdtest.exe программу с -f флагом. Этот флаг очищеят кэш перед каждым тестом. Вы увидите, prefetching может удвоить скорость вашего кода в наихудшем случае. Это легко запоминающийся способ оптимизации, при том, что prefetching команды могут быть использованы даже в не-SIMD коде!
Автор: pavel1978
Дата сообщения: 03.09.2012 17:32
ДСВ!
Братья и сестры! Отечество мое в опасности!
Не надо программу писАть, ниче не надо подиалогался с преподом насчет проследить цепочку памяти МСВ:


Вопрос:
По программе peek.com :
1)    что всё-таки показывает столбец слева и поле по середине этой программы?
Столбец слева – это адрес дампа памяти, который состоит из двух частей: сегмент и смещение.
Столбец по середине – это содержимое (двоичные коды символов из правого столбца) 16 байт памяти, расположенных начиная с адреса указанного в левом столбце.

2)Я получил LoL = 00А7:0026, пытаюсь вычислить адрес MCB по формуле Addr = 16*seg + offset
Addr = 16*A7 + 26 = E80h - правильно делаю?
Правильно, чтобы получить реальный физический адрес. Но по заданию лабораторной вам это нужно знать, но делать не обязательно.
3) База каждого последующего сегмента смещена относительно базы предыдущего на 16 байт (т. н. параграф), т.е. чтобы найти следующий блок мне надо просто добавить 16 (в нех, естесственно) - так?
Вам нужно искать не адреса следующих сегментов, а адреса следующих блоков памяти MCB.
4) можно привести какой-нибудь конкретный пример вычисления блоков памяти? а то я запутался совсем

Чтобы найти адрес следующего блока памяти нужно к сегментному адресу текущего блока памяти (левая часть адреса до двоеточия) прибавить его размер (берется из второго столбца со смещением +3, размером два байта (см. структуру блока MCB), помните по LH-порядок следования байт ), заданный в параграфах и прибавить 1 (единица в сегментном адресе это 16 (10h) байт, величина шапки блока, см. структуру блока MCB, размер задан без этой шапки в параграфах).

дайте тупо эту цепочку, а?
LoL = 00a7:0026(h) Я с ума й....нусь с конкретно этого задания и такой "проги", как peek.com (ею надо проследить эту долбаную цепочку
Автор: MERCURY127
Дата сообщения: 03.09.2012 17:47

Цитата:
Addr = 16*A7 + 26 = E80h - правильно делаю?

нет, не правильно

Цитата:
Отечество мое в опасности

аська есть? чип & дейл спешат на помощь...
Автор: pavel1978
Дата сообщения: 04.09.2012 09:20
хорошо, тогда как правильно-то? (глумиться не надо)

Добавлено:
Цитирую рецензию:

"2)Я получил LoL = 00А7:0026, пытаюсь вычислить адрес MCB по формуле Addr = 16*seg + offset
Addr = 16*A7 + 26 = E80h - правильно делаю?
Препод:
Правильно, чтобы получить реальный физический адрес. Но по заданию лабораторной вам это нужно знать, но делать не обязательно."
Автор: MERCURY127
Дата сообщения: 04.09.2012 15:38
pavel1978, ICQ 5семь293пять88ноль. могу с задержкой ответить, пользуюсь редко...
Автор: Abs62
Дата сообщения: 04.09.2012 17:02
pavel1978

Цитата:
Addr = 16*A7 + 26 = E80h - правильно делаю?

Как можно смешивать французский с нижегородским шестнадцатиричные числа с десятичными?
Addr = 10h*A7h + 26h = 0A96h
Автор: pavel1978
Дата сообщения: 05.09.2012 00:27

Цитата:
Addr = 10h*A7h + 26h = 0A96h

это правильно? (один из моих вариантов рассуждений был такой. А каков след МСВ, его сегмент и оффсет?

Добавлено:
и вот смотри, получили мы 0A96h. Был 00A7:0026h. А теперь 000А:0096h что ли? Я говорю, учебник наглухо мутный и сжатый, поэтому и спрашиваю...
Автор: Abs62
Дата сообщения: 05.09.2012 00:42
pavel1978

Цитата:
А теперь 000А:0096h что ли?

А подставить эти числа в ту же самую формулу и посмотреть, что из этого получается, никак нельзя?

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384

Предыдущая тема: .NET GUI компоненты


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.