Авторские статьи Ассемблер для самых маленьких

Discussion in 'Статьи' started by Vollkorn, 9 Dec 2010.

  1. Vollkorn

    Vollkorn Member

    Joined:
    6 Nov 2010
    Messages:
    86
    Likes Received:
    15
    Reputations:
    -6
    Ассемблер для самых маленьких​


    План:
    1) Введение
    2) Пару слов про асм
    3) Tasm
    4) Регистры, сегменты
    5) Команды асма
    6) Первая прога
    7) Разбор программы
    8) Функции
    9) Стек
    10) Команды перехода
    11) Циклы
    12) Процедуры
    13) Include
    14) Написание программы, используя полученные знания
    15) Вывод

    Начнем.
    I Введение
    Здравствуйте, Античатовыцы. Эту статью я хочу посвятить тем, кто хочет изучать ассемблер (т.е. тем, кто еще не начал, ну или начал, но совсем чуть-чуть). На нашем форуме я не обнаружил ни одной статьи для начинающих учить ассемблер. Есть много постов, где выкладывают книги по асму, так же есть тема, где новички задают вопросы, и статья про cracking, но именно статьи про программирование на асме для новичковнет. Именно это побудило меня её написать. Для начала я хочу сказать, что эта статья только для новичков, так как в ней нету ничего сложного. Просто, например, когда я начинал учить асм, при прочтении книжек я много чего не понимал, почему это именно сбда и так далее. В этой статье я же постараюсь объяснить как можно более простым языком, что к чему. И последнее во введении, я бы написал, что это моя первая статья, и что я новичок, и что не надо тапками кидать, но меня это жутко бесит, поэтому исправляйте и дополняйте меня пожалуйста, но не обзывайтесь, если можете... Это немного обидно)

    II Пару слов про асм

    Язы́к ассе́мблера (в отечественных источниках, также автокод) — язык программирования низкого уровня, мнемонические команды которого (за редким исключением) соответствуют инструкциям процессора вычислительной системы. Трансляция программы в исполняемый машинный код производится ассемблером (от англ. assembler - сборщик) - программой-транслятором, которая и дала языку ассемблера его название. (источник Википедия)

    III Tasm

    Что нам понадобится. Tasm.exe (сам ассемблер), tlink.exe (линковщик), rtm.exe. Вот этих 3 программок хватит. В конце статьи я выложу ссылки на эти программки. Думаю все уже догадались, что всё мы будем делать в Tasm'е) И хоть многие говорят, что Tasm фигня, и т.д., ИМХО ТАСМ -- удобная штука. Вобщем я дам толчок, а дальше Вы уже сами решайте какой ассемблер Вам использовать. Чтобы было удобнее компилировать программы, можете написать небольшой *.bat файл, с содержанием, подобным этому:

    bin/tasm название_файла.asm > asm_log.txt
    bin/tlink название_файла.obj > link_log.txt


    Думаю не сложно догадаться, что этот файл делает =)

    IV Регистры, сегменты
    Наверно большинство тех, кто сейчас это читает, знают, что почти всё в программировании на ассемблере связано с регистрами.
    Прежде всего нужно знать, что регистр -- это сверхбыстрая оперативная память (СОЗУ) внутри процессора. Различают несколько видов регистров: регистры общего назначения (eax/ax/ah/al и т.д.), сегментные регистры (cs, ss, ds и т.д.) и регистры состояния и управления (eip/ip, eflags/flags).

    Регистры общего назначения используются для хранения промежуточных данных, таких как: операдны* логических и арифметических операций, указатели на ячейки памяти и так далее. Примером могут послужить следующие регистры:

    регистр-аккумулятор (EAX) -- применяется для хранения промежуточных данных (немного позже Вы увидите как он используется);
    базовый регистр (EBX) -- применяется для хранения базового адреса некоторого обьекта в памяти (если не поняли, особо не думайте об этом =) );
    регистр-счетчик (ECX) -- регистр используется в основном для организации циклов (о циклах будет рассказано позже);
    регистр данных (EDX) -- так же как и регистр EAX, хранит промежуточные данные.

    Среди всех регистров общего назначения, хочется уделить немного больше внимания регистру ESP. Его не стоит использовать для хранения промежуточных данных, так как в нем хранится указатель на вершину стека (про стек будет дальше).
    Еще хочется отметить, что регистры общего назначения разделяются на несколько меньших, ну... вобщем вот пример:
    EAX (регистр-аккумулятор) -- 32 бита, его 16-ти байтный регистр -- AX, который, в свою очередь, разделяется на регистры AH и AL, по 8 байт. (EBX/BX/BH/BL; ECX/CX/CH/CL и т.д.).

    Сегментные регистры. В процессорах Intel поддерживается сегментная организация программы. Любая программа состоит из трех регистров: стека, данных и кода. К каждому сегменту относится определённый регистр. Всего существует 6 сегментных регистров: CS, SS, DS, ES, GS, FS.
    Сегмент кода -- думаю не сложно догадаться, что именно в этом сегменте содержатся все команды программы =) Особо заморачиваться в начале с этим не надо, просто запомните, что сегменту кода соответствует регистр CS. Что с этим делать я покажу позже.
    Сегмент данных -- тут содержатся данные, которые обрабатываются командами, которые находятся в сегменте кода. Сегменту данных соответствует регистр DS.
    Сегмент стека -- про стек расскажу чуть позже, пока запомните, что сегменту стека соответствует регистр SS.
    Дополнительный сегмент данных -- думаю название говорит само за себя, особо об этом сегменте не думайте. Этому сегменту соответствуют остальные сегментные регистры (ES, GS, FS).

    Регистры состояния и управления. В процессор включены два регистра, которые содержат информацию о самом процессоре, и о программе, которая сейчас выполняется.
    Регистр-указатель -- EIP/IP;
    регистр флагов -- EFLAGS/FLAGS.
    С помощью этих регистров можно управлять состоянием процессора. Тут можно много чего писать, так что если Вам, дорогой читатель, интересно, прочитайте сами.

    *операнд -- это такая штука, обозначающая объекты, над которыми производятся действия.

    V Команды ассемблера

    Думаю те, кто читает эту статью не раз видели ассемблер "в лицо" ) Система команд в этом языке программирования не так сложна, как кажется. Главное запомнить, что в конце каждой строки не обязательно ставить точку с запятой (хотя это может только у меня такая проблемма после си), так как точка с запятой -- это комментарии. Ни для кого не секрет, что внутри компьютера всё записывается как нули и единички (образно говоря), т.е. в двоичном коде. Программирования первых компьютеров именно так и осуществлялось, с помощью только нулей и единиц. Вскоре люди поняли, что это не очень удобно использовать только нолики и единички, поэтому был придуман язык ассемблера, как симолический аналог машинного языка. Отсюда можно сделать вывод, что машинные команды -- это определенно сформированная последовательность нулей и единиц. Что бы было более понятно, приведу пример самой распространенной команды:
    mov ebx, eax*
    Эта команда копирует содержимое регистра eax в регистр ebx.
    Такая же машинная команда будет выглядеть так:
    8B D8
    Значение 8B -- код операции. Вот еще один пример:
    mov ecx, 128
    Эта команда записывает в регистр ecx десятичное число 128. Такая же машинная команда выглядет так:
    B9 00000080
    Как вы видите, несмотря на то, что команда в обеих примерах одна и та же (MOV), коды машинных команд разные. Отсюда можно сделать вывод, что большинство команд ассемблера могут по разному переводится в машинные команды, это зависит от операндов, с которыми они работают.

    *mov приемник, источник. Запомните эту команду, она вам очень понадобится.

    VI Первая программа

    Итак, пришло, наконец-то, время для написания нашей первой программы. Это будет самая простая программка "Hello Antichat!". Думаю вы поняли, что она будет делать (кто не понял, объясняю, это программка будет выводить сообщение "Hello Antichat!").
    Я сразу выложу вам код, а после него мы разберем эту программку.

    Code:
    MODEL SMALL              		  ; Объявляем модель памяти              
                    STACK 256    		 ; Объявляем размер стека        
    DATASEG                  			 ; Начало сегмента данных          
              msg db 'Hello Antichat! $'              ; создаем переменную msg с текстом "Hello Antichat!"
    CODESEG                     		 ; Начало сегомента кода
    start:                            			 ; "вход в главную часть"
              mov ax, @data    			 ; связываем сегмент данных 
              mov ds, ax         			 ; с регистром ds 
              mov dx, offset msg 		 ; в регистр dx аддрес переменной msg
              mov ah, 09h     			 ; в регистр ah 09h
              int 21h              			 ; прерывание №21
              mov ah, 1h                                   ; в регистр ah - 1h
              int 21h				 ; прерывание 21
              mov ah, 04ch     			 ; в регистр ah 04ch
              int 21h              			 ; прерываение 21
    end start				 ;закончить "главную часть"
    VII Разбор программы

    Итак, теперь по порядку.
    1 строка -- эта команда определяет модель сегментации программы, чтоб сильно Вас не нагружать скажу в двух словах, для небольших программок (а мы пока что такие и пишем), используйте модель SMALL (т.е. код занимает один сегмент, данные объеденены в одну группу с именем DGROUP.) В конце статьи я укажу ссылки, и литературу, где можно об этом прочитать.
    2 строка -- в комментарии уже сказал, добавить нечего, объявляем размер стека
    4 строка -- создаем переменную msg типа db. На этом мне бы хотелось немного остановится. Совсем капельку. Существует три типа переменных db (Data Byte), dw (Data Word) и dd (Data Doubleword). Что ж, я, например, в большнистве случаев использую db и, пока-что, в начале обучения, советую тоже использовать db. Вы спросите, зачем знак доллара в конце строки? Я отвечу, знак доллара мы пишем, чтоб можно было использовать удобную функцию ассемблера для вывода строки. Об этом я скажу позже.
    7-8 строка -- помните я говорил, что существуют сегментные регистры, и что каждый из них соответствует определенному сегмунту? Так вот, в этих двух строках, используя промежуточный регистр ax, вы записываем в регистр ds физический адресс сегмента данных.
    9 строка -- в регистр dx помещаем адресс переменной msg, почему именно так, я расскажу слудеющем разделе.
    10 строка -- в ah записываем 09h, зачем это делать, я опять таки расскажу в следующем разделе.
    11 строка -- операция прерывания дос. Int сокращенно от interupt, что переводится как прерывание.
    12 строка -- в регистр ah 04ch
    13 строка -- операция прерывания
    14 строка -- закончить "главную часть"
    Думаю стало немного более понятно.

    VIII Функции

    Когда я начинал учить ассемблер, мне было не понятно, почему именно те числа помещаем именно в тот регистр, и почему именно то, помещаем сюда. Объясняю для таких, как я =)
    В ассемблере тоже есть функции, с некоторыми из них мы встречались в шестом разделе, когда писали первую программку. Давайте вспомним:

    1) mov dx, offset msg
    mov ah, 09h
    int 21h
    2) mov ah, 04ch
    int 21h


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

    Функция вывода строки на экран:
    в ah надо поместить 09h, а в dx то, что надо выводить, в нашем случае, мы поместили в регистр dx адресс нашей строки, так как наша строка слишком длинная для помещения её в этот регистр. Что бы использовать функцию 09h, надо, чтоб в конце строки был символ доллара (вот мы и узнали зачем он там).

    Функция выхода из программы:
    в ah нужно поместить значение 04ch, и вызвать операцию прерывания.

    Eщу одна функция вывода строки (мы её не использовали, так как она сложнее той, что мы использовали):
    в регистр dx -- то, что надо вывести
    в регистр cx -- количество выводимых символов
    в регистр bx -- устройство, куда записывать, в нашем случае 1
    в регистр ah -- 40h, сам код этой функции

    Считать символ (там много чего запутано, будем пока его использовать, что после выполения программы, окно доса не закрывалось, а ждало пока мы нажмем клавишу)
    в ah -- 1h
    в al -- появится символ, который вы ввели.


    Ну...я думал дать еще пару функций, потом передумал, так как решил, что они вам пока не нужны =)
    Как вы уже заметили, после того, как всё помещено по нужным регистрам, нудо вызвать прерывание. Запомните это.
    Такс, с функциями слегка разобрались. Пойдем дальше.

    IX Стек

    Нууу, стек -- это такая область памяти. Адресацией в стеке занимается регистр es. В основном, стек используется для временного хранения содержимого регистров. Стоит помнить, что именно для ВРЕМЕННОГО. Стек работает по принципу LIFO, Last In Firs Out. Т.е. последний элемент, который положили в стек, должен первым оттуда выйти. Примером может послужить обойма автомата. Думаю все когда нибудь держали в руках обойму от автомата. В школе, в старших классах на подготовке к армии должны были. Первая пуля, которая была туда засунута вылетит последней, а последняя засунутая -- первой. Команды для работы со стеком следующие:
    push -- положить в стек
    pop -- вытащить из стека

    Как пример, возьмем кусок кода программы:
    blah-blah ; какие-то действия
    mov ax, 21 ; в регистр ax число 21
    push ax ; значение регистра ax в стек
    mov ah, 09h ; какие то оперции, в которых замешан регистр ax
    blah-blah
    pop ax ; вытащить из стека


    В результате, в регистре ax будет число 21. Думаю и со стеком разобрались. Повторяю, я не углубляюсь в каждую из тем, я просто хочу дать первый толчок людям, которые начали изучать ассемблер.

    X Команды перехода

    Ну а как же без них. Хех. Благодаря командам перехода, на ассемблере мы можем программировать типовые управляющие структуры, if-else и так далее. Но для этого надо познакомится с командой cmp. Те, кто учил си, должны знать, что в си есть функция strcmp, которая сравнивает строки. Подобная команда есть и в асме.
    CMP (сокращенно от compare) команда, которая сравнивает два значение. Синтаксис у неё следующий:
    cmp операнд1,операнд2
    Следующим этапом, чтобы понятькоманды перехода, надо понять, что такое метки. Метки, в языке ассемблера, используются, чтоб сделать программу более понятной, ну и чтобы можно было, при определенных условиях, на них переходить. Метка объявляется следующим образом:
    Имя_метки:
    Т.е. пишем название метки, и двоеточие. Такс, с метками тоже разобрались, ну это не сложно, но метки очень полезны.
    И наконец команды перехода. Их можно разделить на две группы: команды безусловного перехода и команды условного перехода.
    Команды безусловного перехода. Единственная команда безусловного перехода, которую мы рассмотрим -- jmp. Все мы знаем слово "jump", т.е. прыжок, вот сокращение этого слова, jmp, и есть команда безусловного перехода. Не, ну всё логично, прыгнуть на определенную метку. Так, что-то я отвлекся, продолжим. Синтаксис у этой команды такой:
    jmp метка
    Думаю тут ничего сложного нет.
    Команды условного перехода. То есть те команды перехода, которые выполняются по определенному условию. Вспомним начало этого раздела, команда cmp, в основном, команды условного перехода выполняются после этой команды. Я приведу небольшой список этих команд:

    je / jne прыгнуть, если равны / если не равны
    jg / jng / jge прыгнуть, если больше / если не больше / если больше или равны
    jl / jnl / jle прыгнуть, если меньше / если не меньше / если меньше или равны
    ja / jna / jae прыгнуть, если выше (в смысле больше) / если не выше (в смысле больше) / если выше (в смысле больше) или равны
    jb / jnb / jbe прыгнуть, если ниже (в смысле меньше) / если не ниже (в смысле меньше) / если ниже (в смысле меньше) или равны

    Вначале каждой команды стоит буква j, означающая jump, прыгнуть. Далее идет условие (чтобы понять почему именно так, надо вспомнить некоторые английские слова: equal, not, above, below, greater, less, перевод найдите в словаре).

    Лучше посмотреть на примере. Я не буду писать целую программу. только небольшой её кусочек.

    mov ax,22
    mov bx,21
    cmp ax,bx
    je Equal
    jg Greater
    jl Less

    Equal:
    ; вывести сообщение, что равны
    Greater:
    ; вывести сообщение, что операнд 1 больше оперенда 2
    Less:
    ; вывести сообщение, что операнд 1 меньше оперенда 2


    На этом, про команды перехода хватит.

    XI Циклы
    Думаю не стоит объяснять, что такое циклы, поэтому сразу перейдем к делу. Для того, чтобы организовать цикл на ассемблере, есть два пути (может есть и больше, но мы их рассматривать не будем). Первый способ: в этом способе нам придется использовать команду условного перехода jcxz, переход будет выполнен только если в регистре cx будет 0. Давайте я приведу пример кода.

    ; blah-blah ; объявляем какие то данные
    mov cx, 10 ; кидаем в регистр cx число, сколько будет тиков в цикле
    m1: ; первая метка
    dec cx ; вы еще не знакомы с этой командой, но она очень проста, декремент регистра cx, подобная команда есть inc -- инкремент

    mov dx, offset msg ;
    mov ah, 09h ; выводим какое-то сообщение
    int 21h ;

    jcxz exit ; если регистр cx равен нулю, переходим на метку exit
    jmp m1 ; иначе переходим на метку m1
    exit: ; метка exit
    mov ah, 04ch ; выход из программы
    int 21h


    Как вы видите, всё просто, помещаем в регистр cx сколько раз должен повторится цикл, уменьшаем cx на один, выполняем действия, проверяем равен ли cx нулю, если да -- переходим на метку exit, если нет -- повторяем.

    Второй способ: второй способ не требует использования команды перехода, во втором способе используется команда loop. Эта команда переводит нас на указанную метку пока cx не равен нулю. Давайте перепишем раннее написаный кусок кода, использовав команду loop.

    ; blah-blah ; объявляем какие то данные
    mov cl, 10 ; кидаем в регистр cx (cl) число, сколько будет тиков в цикле
    m1: ; первая метка
    mov dx, offset msg ;
    mov ah, 09h ; выводим какое-то сообщение
    int 21h ;

    loop m1 ; повторить m1, если cx не равен нулю
    exit: ; метка exit
    mov ah, 04ch ; выход из программы
    int 21h


    Вот и разобрались с циклами.

    XII Процедуры

    Мы уже "много" чего умеем, не так ли?) Но Вы не заметили, что некоторые участки кода повторяются? Конечно же заметили, для того, чтобы сделать код более читабельным и понятным придумали некие процедуры. Думаю вы уже догадались, что это такое, и объяснять это не стоит. Простая процедура объявляется следующим образом:

    имя_процедуры PROC
    какие-то_действия
    ret
    имя_процедуры ENDP

    Как вы видите, ничего сложного нет. Например мы знаем, что для того, чтобы вывести текст на экран, надо в регистр ah поместить 09h, и вызвать прерывание 21 (int 21). Давайте объеденим это в процедуру. Получится что-то такое:

    Write PROC
    mov ah, 09h
    int 21h
    ret
    Write ENDP


    Используйте процедуры, чтобы сделать код понятнее.

    XIII Include

    В прошлом разделе мы познакомились с вами с процедурами. Благодаря процедурам можно сделать код понятнее. Так же есть директива include, которая позволяет нам включать куски кода из одного файла в другой. Уловили мысль? Мы напишем нужные процедуры, поместим их в отдельный файл, и просто его проинклудим. Таким образом код станет еще проще. Синтаксис у этой команды такой:

    include файл.asm

    Ничего сложно. В следующем шаге, мы напишем программу, используя эту директиву, поэтому в этом разделе я не буду приводить пример.

    XIV Написание программы, используя полученные знания

    Сейчас я приведу вам код программы, используя все знания, которые Вы получили (ну по крайней мере, могли бы получить). Сама программка будет очень глупой, и мы будем делать много лишних действий, но так надо, чтобы использовать все полученные знания =)
    После кода программы, я построчно приведу объяснение. В самом коде я не буду оставлять комментариев (слегка геморойно мне сейчас это делать), а после программы всё объясню. Итак, код:

    Code:
    ; ach.asm
    MODEL SMALL
    STACK 256
    DATASEG
    	bye db 'The end!) $'
    	msg1 db 'CX < 5 || $'
    	msg2 db 'CX > 5 || $'
    	msg3 db 'CX = 5 || $'
    CODESEG
    start:	
    	mov ax, @data
    	mov ds, ax
    
    	mov dx, offset bye
    	mov cx, 5
    	push dx
    	push cx
    
    	jmp begin
    	include achadd.asm
    begin:
    	mov cx, 7
    	cmp cx, 5
    	je m3
    	jg m2
    	jl m1
    m3:
    	mov dx, offset msg3
    	call write
    	jmp preexit1
    m2:
    	mov dx, offset msg2
    	call write
    	jmp preexit1
    m1:
    	mov dx, offset msg1
    	call write
    preexit1:
    	pop cx
    	pop dx
    preexit2:
    	call write
    	loop preexit2
    ext:
    	call exit
    end start
    
    ;#############################
    Code:
    ;achadd.asm
    write proc
    
    mov ah,09h
    int 21h
    ret
    
    write endp
    ;+++++++++++++++++++++++++;
    exit proc
    
    mov ah, 1h
    int 21h
    mov ah, 04ch
    int 21h
    ret
    
    exit endp
    
    Тут у нас два файла, в первом главный код, во втором две процедуры.
    Начнем с первого файла:
    1 строка -- объявляем модель памяти
    2 строка -- объявляем размер стека
    3 строка -- начало сегмента данных
    4-7 строки -- создаем переменные с сообщениями
    8 строка -- начало сегмента кода
    9 строка -- входим в "главную часть"
    10-11 строки -- связываем данные с их сегментным регистром
    13 строка -- записываем в регистр cx адрес переменной bye
    14 строка -- в регистр cx помещаем 5
    15 строка -- помещаем регистр dx в стек
    16 строка -- помещаем регистр cx в стек
    18 строка -- перепрыгиваем на метку begin
    19 строка -- инклудим файл achadd.asm
    20 строка -- объявляем метку begin
    21 строка -- записываем в регистр cx число 7
    22 строка -- сравниваем то, что в регистре сч с числом 5
    23 строка -- если равные переходим на метку m3
    24 строка -- если cx больше 5, переходим на метку m2
    25 строка -- если cx меньше 5, переходим на метку m1
    26 строка -- объявляем метку m3
    27 строка -- записываем в dx адрес переменной msg3
    28 строка -- вызываем процедуру write
    29 строка -- прыгаем на метку preexit1
    30-36 строки -- объявляем метки, записываем определенные сообщения и вызываем процедуру write (долго расписывать)
    37 строка -- объявляем метку preexit1
    38 строка -- вытаскиваем значение со стека в регистр cx
    39 строка -- вытаскиваем значение со стека в регистр dx
    40 строка -- объявляем метку preexit2
    41 строка -- вызываем процедуру write
    42 строка -- повторям, пока cx не станет равен нулю
    43 строка -- объявляем метку ext
    44 строка -- вызываем процедуру exit
    45 строка -- end start

    Второй файл, разберите сами, это будет как маленькое д.з.)) там ничего сложного нет.

    XV Вывод

    Ну, вот и всё) в этой статье я хотел показать, что ассемблер не такой уж и сложный язык (пока Вы не начнете учить что-то по-серьезнее, хе-хе). И хоть мы рассмотрели только основы, они будут очень полезны всем, кто хочет кодить не только на делфи)

    Ну и ссылка на тасм, http://letitbit.net/download/5627.a5de7462230205a7a148f13dd/1065_tasm.rar.html
    Рекомендую для прочтения книгу В.И. Юрова, Assembler 2-е издание.

    Удачи в изучении ассемблера)
     
    5 people like this.
  2. HBWS

    HBWS Member

    Joined:
    26 Nov 2010
    Messages:
    226
    Likes Received:
    22
    Reputations:
    0
    Все по полочкам, молодец. Честно говоря не ожидал, что статья будет такой интересной
     
  3. .brynet

    .brynet New Member

    Joined:
    25 Feb 2010
    Messages:
    0
    Likes Received:
    1
    Reputations:
    0
    все грамотно расписанно! молодец.
     
  4. Vollkorn

    Vollkorn Member

    Joined:
    6 Nov 2010
    Messages:
    86
    Likes Received:
    15
    Reputations:
    -6
    Люди, я специально не выкладывал много литературы, на античате есть тема, где есть много книг по ассемблеру
    https://forum.antichat.ru/thread94535-%EB%E8%F2%E5%F0%E0%F2%F3%F0%E0+%E0%F1%F1%E5%EC%E1%EB%E5%F0.html
     
    1 person likes this.
  5. cheater_man

    cheater_man Member

    Joined:
    13 Nov 2009
    Messages:
    651
    Likes Received:
    44
    Reputations:
    7
    Статья ниче, но про прерывания тема не раскрыта=)
     
  6. Vollkorn

    Vollkorn Member

    Joined:
    6 Nov 2010
    Messages:
    86
    Likes Received:
    15
    Reputations:
    -6
    Я и не собирался писать про прерывания) просто вскольз про них упомянул, чтоб люди знали, что такое существует)
     
    1 person likes this.
  7. Ubagumov

    Ubagumov New Member

    Joined:
    10 Jan 2011
    Messages:
    6
    Likes Received:
    3
    Reputations:
    2
    Автор спасибо, ассемблер очень интересный язык, узнал для себя немного нового ) :)
     
  8. dix2m

    dix2m New Member

    Joined:
    10 Feb 2011
    Messages:
    2
    Likes Received:
    0
    Reputations:
    0
    Спасибо за статью..
    Все отлично рассписано. Только 2 дней изучаю ассемблер.
     
  9. foozzi

    foozzi Member

    Joined:
    13 Apr 2010
    Messages:
    195
    Likes Received:
    12
    Reputations:
    5
    все это и даже больше ест ьв книге калашникова, да и про сегменты там написано подробней, т.к. считается что для новичков освоение сегментов сложно дается
    А статья неплохая
     
  10. Vollkorn

    Vollkorn Member

    Joined:
    6 Nov 2010
    Messages:
    86
    Likes Received:
    15
    Reputations:
    -6
    В книгах обычно всегда лучше расписано) на то они и книги, а это статья) которая мб подтолкнет прочитать книгу)
     
  11. megakill

    megakill New Member

    Joined:
    3 Mar 2011
    Messages:
    4
    Likes Received:
    1
    Reputations:
    0
    + тема