Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.
Внимание! Некоторое время письма не доходят до аккаунтов MAIL RU GROUP, не доходят на все почтовые ящики mail.ru, inbox.ru, bk.ru. Пишите им жалобы, чтобы быстрее восстановили получение писем, регистрируйтесь через яндекс почту и gmail, туда письма с активизацией доходят.

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 05.12.2014, 10:51   #41
Mikl___
Профессионал
 
Регистрация: 11.01.2010
Сообщений: 1,129
Репутация: 943
По умолчанию

  • Графика FASM
    Код:
    
        format MZ
        heap    0
        stack   100h
        entry   main:start
    segment main    use16
    start:  push    0                   
        pop fs                      ; vector table
        mov ax,data_segment
        mov ds,ax
        mov es,ax
        mov ax, 13h            ; modeX Graphics 320x200x256, 40x25, 8x8     
        int 10h
        mov eax, dword [fs:43h*4]
        mov dword [int43], eax     ; Get 8x8 chargen ptr
        mov si, hello
    next:   call    gotoxy
        lodsb
        or  al,al
        jz  exit
        cmp al,20h  ; <space>?
        jnz @1
        add byte [Y], 11
        mov byte [X], 0
        jmp next
    @1: movzx   ax,al
        shl ax, 3   ; ax*8
        push    si
        push    ds
        lds si, [int43]
        add si, ax
    ; Вывод на экран 
        mov cx, 8 
    loo0:   lodsb
        mov bl, al
        push    cx
        mov cx, 8
    loo1:   mov al, 20h
        rcl bl, 1
        jnc @@1
        mov al, 0DBh
    @@1:    int 29h
        loop    loo1
        pop cx
        inc byte [es:Y]
        call    gotoxy
        loop    loo0
        pop ds
        pop si
        add byte [X], 8
        sub byte [Y], 8
        jmp next    
    ; выход
    exit:   xor ah, ah
        int 16h
        mov ax, 03h
        int 10h
        mov ah, 4Ch
        int 21h
    gotoxy: pusha
        mov ah,2
        xor bx,bx
        mov dx, word [es:XY]
        int 10h
        popa
        ret
    segment data_segment use16 
    int43:  dd  ?
    XY:
    X:  db  0
    Y:  db  3
    hello:  db  'Hello world',0
    
    
  • шлём сообщение самому себе через LAN Manager FASM
    Код:
    
            org 100h
            push    cs
            pop ax
            mov [rcpt_seg], ax
            mov [msg_seg], ax
            mov ax, 5E00h   ; DOS 3.1+ network
            mov dx, wkst_nm ; получить
            int 21h             ; имя локальной машины
            mov ax, 5F40h       ; LAN Manager Enhanced DOS
            mov dx, LM_MSG  ; отправить сообщение
            int 21h             ; самому себе
            int 20h
    ; LAN Manager NetMessageBufferSend parameter structure:
    LM_MSG:                                 ;
    ; DWORD -> имя адресата (name for specific user, name* for domain wide name, * for broadcast)
    rcpt_ofs:   dw  wkst_nm
    rcpt_seg:   dw  ?
    ; DWORD -> текст сообщения
    msg_ofs:    dw  msg
    msg_seg:    dw  ?
    msg_sz:     dw  msg_len     ; длина сообщения
    ;
    wkst_nm:    db  10h dup(?)  ; имя рабочей станции
    msg     db  'Hello, World!'
    msg_len     =   $ - msg
    
    
  • Hello world через ESC-последовательности.
    предварительно должен быть загружен драйвер ANSY.SYS
    Код:
    
    .model small
    .stack 256
    .data
         
         msg db 27, '[2J'                              ;очистка экрана
    	 db 27, '[31;47m'	           ;красные символы на белом фоне
    	 db 27, '[12;40H', 'Hello, world!!!'	;текст выводится начиная с 12 строки 40 колонки
    	 db 27, '[0m', 27, '[25;1H$'	;отменить аттрибуты вывода текста и установить курсор на 25 строку 1 стобец
    
    .code
    start:
    	mov ax, @data
    	mov ds, ax
    	
    	mov ah, 9
    	mov dx, offset msg
    	int 21h
    	
    	xor ax, ax
    	int 16h
    	mov ax, 4c00h
    	int 21h
    end start
    
    
Mikl___ вне форума   Ответить с цитированием
Старый 05.12.2014, 10:58   #42
Mikl___
Профессионал
 
Регистрация: 11.01.2010
Сообщений: 1,129
Репутация: 943
По умолчанию

  • Код:
    
    ; пример 64-битного PE файла
    ; для его выполнения необходимо иметь Windows XP 64-bit edition
    
    ; указываем формат
    format PE64 GUI
    
    ; указываем точку входа
    entry start
    
    ; создать кодовую секцию с атрибутами на чтение и исполнение
    section '.code' code readable executable
    start: 
      sub rsp,8		; Make stack dqword aligned
            mov        r9d,0                   ; uType == MB_OK (кнопка по умолчанию)
                                               ; аргументы по соглашению x86-64
                                               ; передаются через регистры, не через стек!
                                               ; префикс d задает регистр размером в слово,
                                               ; можно использовать и mov r9,0, но тогда
                                               ; машинный код будет на байт длиннее
    
            lea        r8,[_caption]           ; lpCaption, передаем смещение
                                               ; команда lea занимает всего 7 байт,
                                               ; а mov reg,offset - целых 11, так что
                                               ; lea намного более предпочтительна
    
            lea        rdx,[_message]          ; lpText, передаем смещение выводимой строки
    
            mov        rcx,0                   ; hWnd, передам дескриптор окна-владельца
                                               ; (можно также использовать xor rcx,rcx
                                               ; что на три байта короче)
    
            call       [MessageBox]            ; вызываем функцию MessageBox
    
            mov        ecx,eax                 ; заносим в ecx результат возврата
                                               ; (Функция ExitProcess ожидает 32-битный параметр;
                                               ; можно использовать и mov rcx,rax, но это будет
                                               ; на байт длиннее)
    
            call       [ExitProcess]           ; вызываем функцию ExitProcess
    
    ; создать секцию данных с атрибутами на чтение и запись
    ; (вообще-то, в данном случае атрибут на запись необязателен,
    ; поскольку мы ничего не пишем, а только читаем)
    section '.data' data readable writeable
    
      _caption db 'Win64 program template',0     ; ASCIIZ-строка заголовка окна
      _message db 'Hello World!',0             ; ASCIIZ-строка выводимая на экран
    
    ; создать секцию импорта с атрибутами на чтение и запись
    ; (здесь атрибут на запись обязателен, поскольку при загрузке PE-Файла
    ; в секцию импорта будут записываться фактические адреса API-функций)
    section '.idata' import data readable writeable
    
            dd 0,0,0,RVA kernel_name,RVA kernel_table
            dd 0,0,0,RVA user_name,RVA user_table
            dd 0,0,0,0,0     ; завершаем список двумя 64-разряными нулеми!!!
    
    kernel_table:
            ExitProcess dq RVA _ExitProcess
            dq 0                        ; завершаем список 64-разряным нулем!!!
    
    user_table:
            MessageBox dq RVA _MessageBoxA
            dq 0
    
    kernel_name db 'KERNEL32.DLL',0
    user_name db 'USER32.DLL',0
    
    _ExitProcess dw 0
            db 'ExitProcess',0
    _MessageBoxA dw 0
            db 'MessageBoxA',0
    
    

Последний раз редактировалось Mikl___; 05.12.2014 в 11:09.
Mikl___ вне форума   Ответить с цитированием
Старый 05.12.2014, 11:09   #43
Mikl___
Профессионал
 
Регистрация: 11.01.2010
Сообщений: 1,129
Репутация: 943
По умолчанию

  • под FreeBSD. include-файлы лежат на https://github.com/graudeejs/asm4BSD...reeBSD/include,
    в файле macros.fasm стр. 21 должна выглядеть так:
    Код:
    
            lea        esp,[esp+4*margc]    ; clear stack
    
    
    Код:
    
    ;fasm helbsd
    ;ld -s -o helbsd helbsd.o
    include 'BSD/macros.inc'
    include 'BSD/syscall.inc'
    STDOUT  = 1
    format ELF
     
    section '.text' executable
    public _start
    _start:
        syscall SYS_WRITE,STDOUT, msg, msg_size
        syscall SYS_EXIT, 0
     
    section '.data' writeable
    msg db 'Hello, FreeBSD world!',0xA
    msg_size = $-msg
    
    
  • FreeBSD вызываем системную библиотеку libc.so
    Код:
    
    ; fasm example of using the C library in Unix systems
    ; compile the source with commands like:
    ;   fasm libcdemo.asm libcdemo.o
    ;   gcc libcdemo.o -o libcdemo
    ;   strip libcdemo
    format ELF
     
    include 'ccall.inc'
     
    struc tm
    {
    .tm_sec:    rb  2 ;  seconds after the minute -- [0,61]
    .tm_min:    rb  2 ;  minutes after the hour   -- [0,59]
    .tm_hour:   rb  2 ;  hours after midnight     -- [0,23]
    .tm_mday:   rb  2 ;  day of the month         -- [1,31]
    .tm_mon:    rb  2 ;  months since January     -- [0,11]
    .tm_year:   rb  2 ;  years since 1900
    .tm_wday:   rb  2 ;  days since Sunday        -- [0,6]
    .tm_yday:   rb  2 ;  days since January 1     -- [0,365]
    .tm_isdst:  rb  2 ;  Daylight Savings Time flag
    tm_size =   $ - .
    }
     
    section '.text' executable
     
     public main
     extrn printf
     extrn time
     extrn strftime
     extrn localtime
     
     main:
        ccall   time, 0     ; получить время в сек. от 00:00:00 1-jan-1970
        mov [now],eax
        ccall   localtime, now  ; преобразовать в структуру tm и получить указатель
        mov [ptime], eax
    ; преобразовать дату/время в строку ДД-месяц-ГГГГ ЧЧ:ММ:СС день_недели
        ccall   strftime, buf, BUFF_SZ, fmt, [ptime]
        ccall   printf, msg, buf; вывод на экран
        ret
     
    section '.data' writeable
    BUFF_SZ =   35
    now:    dd  0
    ptime   dd  ?
    fmt db  '%d-%B-%Y %T, %A',0
    msg db  "Hello, FreeBSD world!",0xA, 0xD,"Now %s.",0xA,0
    buf rb  BUFF_SZ
    
    
  • Linux (x86)
    Код:
    
    global main
    extern printf
     
    section .code
    main:
            mov     eax, [esp+8]
            mov     eax, [eax]
            push    eax
            push    msg
            call    printf
            add     esp, 8
     
            mov     eax, 0
            ret
     
    section .data
    msg     db "Hello World!!!", 10
            db "My name is '%s'", 10, 0
    
    
    компиляция выполняется через
    Код:
    
    ~/work$ nasm -f elf32 hello.asm -o hello.o
    ~/work$ gcc hello.o -o hello
    ~/work$ ./hello
    Hello World!!!
    My name is './hello'
    
    
  • Win64 NASM
    Код:
    
    global main
    extern printf
     
    section .code
    main:
            sub     rsp, 4*8
     
            mov     rdx, [rdx]
            mov     rcx, msg
            call    printf
     
            add     rsp, 4*8
            mov     rax, 0
            ret
     
    section .data
    msg     db "Hello World!!!", 10
            db "My name is '%s'", 10, 0
    
    
    Компиляция и компоновка (MinGW64):
    Код:
    
    D:\Work>nasm -f win64 hello.asm -o hello.obj
    D:\Work>x86_64-w64-mingw32-gcc hello.obj -o hello.exe
    
    
  • Linux (x64) NASM
    Код:
    
    global main
    extern printf
     
    section .code
    main:
            mov     rax, 0
            mov     rsi, [rsi]
            mov     rdi, msg
            call    printf
     
            mov     rax, 23
            ret
     
    section .data
    msg     db "Hello World!!!", 10
            db "My name is '%s'", 10, 0
    
    
    Компиляция, компоновка:
    Код:
    
    ~/work$ nasm -f elf64 hello.asm -o hello.o
    ~/work$ gcc hello.o -o hello
    
    

Последний раз редактировалось Mikl___; 05.12.2014 в 11:43.
Mikl___ вне форума   Ответить с цитированием
Старый 05.12.2014, 12:01   #44
Mikl___
Профессионал
 
Регистрация: 11.01.2010
Сообщений: 1,129
Репутация: 943
По умолчанию

Графика DOS. Падающий снег в 3D
Код:

; masm dos com #
.model tiny
.code
.386
org 100h
maxpix	equ 5000
WIDTH_SCREEN	equ 320
HEIGHT_SCREEN	equ 200
SCREENSIZE	equ WIDTH_SCREEN*HEIGHT_SCREEN
IMPUT_STATUS_0	equ 3DAh	;регистр статуса ввода 0
VGA_SEGMENT	equ 0A000h
ftmp	equ dword ptr [bp-4]
tmp	equ word ptr [bp-6]
c_	equ byte ptr [bp-6-maxpix]
s	equ word ptr [bp-6-3*maxpix]

start:	enter	6+3*maxpix,0
	mov ax,13h
	int 10h		; - VIDEO - SET	VIDEO MODE
	mov ax,cs
	add ax,1000h
	mov gs,ax
	finit
; Инициализация снега
	mov si,maxpix
	xor ax,ax
@@:	xor ax,bx          ;Random by Alexander Matchugovsky (2:5020/996.21)
	add ax,ax
	adc bx,0
	xor bx,ax
	mov s[si],ax
	shr al,4
	inc ax
	mov c_[si],al
	dec si
	jnz @b
	fldz    ;stf=0
mainloop:push gs
	pop es;es=gs
 	xor di,di
	xor eax,eax
	mov cx,SCREENSIZE/4
	rep stosd
	mov si,maxpix
@@:	fld st;	fld stf
	fsin
	movzx eax,byte ptr c_[si];ftmp=c[SI]*5;
	imul eax,5
	mov ftmp,eax
	fmul ftmp
	fistp tmp
	mov ax, s[si]
	add tmp, ax      ;tmp+=s[SI];DI=tmp;
	mov di, tmp
	mov al, c_[si]
	add al,15        ;AL=c[SI]+15;
	stosb  ;GS:[DI]=AL;
	xor ax,ax
	mov al,c_[si]
	add ax,16
	shr ax,3
	imul ax,WIDTH_SCREEN
	add s[si], ax   ;s[SI]+=((c[SI]+16)/8)*320;
	sub si,2
	jnz @b
	fadd const005  ;stf+=0.05
	mov dx,IMPUT_STATUS_0; тормозим вывод на экран до следующего кадра
WaitVerticalSync:in al,dx
	test al,8
	jz WaitVerticalSync
WaitNotVerticalSync:in al,dx
	test al,8
	jnz WaitNotVerticalSync
	push VGA_SEGMENT
	pop es
	xor di,di
	mov cx,SCREENSIZE/4
	rep movs dword ptr es:[di],gs:[si]
	mov es,cx
	mov ax,es:[41Ah]
	sub ax,es:[41Ch]; было ли нажатие на клавиатуру?
	jz mainloop
	mov ax,3;восстанавливаем текстовый режим
	int 10h
	int 20h; выход из программы
const005	dd 0.05
end start

Mikl___ вне форума   Ответить с цитированием
Старый 05.12.2014, 12:35   #45
Stilet
Белик Виталий :)
Профессионал
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Адрес: Украина, Донецкая область, г. Краматорск
Сообщений: 57,842
Репутация: 6832
По умолчанию

На всяки случай и я кое-что подброшу.
Ввод и вывод числа в DOS

Код:

format MZ
include 'D:\fasmw16726\INCLUDE\win32a.inc'
push	cs
pop	ds

;Вызовим функцию считки числа
;Она вернет в AX считанное с консоли число
 call readint
;Что-то с числом сделаем
 add ax,3
;И выведем его в консоль
 call writeint

;Чтоб консоль не сразу закрылась попросим ее подождать нажатия клавиши
 mov	 ah, 1
 int	 21h		 ; DOS - KEYBOARD INPUT

;Потом вызовем функцию корректного завершения программы
 mov	ah, 4Ch
 int	 21h

 ret

 ;Сама функция считывания числа основана на символьном считывании нажатий в консоли
 ;и превращения символа в число путем вычитания из его кода некоего начального значения
 ;Начальным значением послужит код символа 0, поскольку это число в таблице символов первое
;Считываем число в регистр АХ
proc readint
;Приготовим рееестры. АХ нужен для считывания символа
 xor ax,ax
;ВХ для формирования числа по считанным символам
 xor bx,bx

 ;Начнем цикл считывания
inp:
;Попросим ДОС считать с консоли символ, введенный с клавиатуры
 mov	 ah, 1
 int	 21h		 ; DOS - input
 ;Если код символа равен 13 т.е. это Энтер
 cmp al,13
 ;Завершим считывание из консоли и по факту приготовимся выходить из функции
 je next
 ;Иначе из кода считанного символа отнимем код нуля, получив цифру в числовом виде
 sub al,'0'
 ;и приплюсуем его к результату
 add bl,al
 ;Не забыв умножить на 10, чтоб получить десятки, сотни, тысячи и т.д.
 mov ax,10
 xchg ax,bx
 mul bx
 xchg ax,bx
 ;После чего перейдем на следующую итерацию цикла для получения следующего числа
 jmp inp
next:
;Если нажат Энтер то разделим результат на 10, чтоб убрать мусор
 mov ax,bx
 mov bx,10
 div bx
;И оставив результат в АХ выйдем из функции
 ret
endp

;Пишем число на консоль из АХ
proc writeint
;Для этого проведем обратное преобразование, деля число на 10 и получая его остатки
 mov bl,10
 xor cx,cx
;Проблема в том что мы заранее не знаем сколько цифр в числе, поэтому каждый остаток от
;деления придется помещать в стек - получис массив цифр числа
for:
;На каждой итерации цикла деления вычисляем кол-во цифр, занося его в регистр СХ
 inc cx
;Далее делим число на 10
 div bl
 xor dx,dx
 mov dl,ah
;И помещаем цифру числа в стек
 push dx
 xor ah,ah
 cmp al,10
 jg for
 push ax
;После разворота числа на массив цифр
 inc cx
;укажем что хотим использовать ДОС функцию прерывания 21h, которая умеет выводить символ на экран
 mov ah,2
;Начинаем цикл вывода
output:
;Получаем цифру из стека с конца
 pop dx
;Прибавляем к ней код символа ноль, чтоб она выглядела в консоли как цифра
 add dl,'0'
;И просим DOS вывести на экран
 int 21h
 loop output
 ret
endp

;section '.data' data readable writable
s db 100 dup('$')
y dw ?
x3 dw 20

__________________
I'm learning to live...

Последний раз редактировалось Stilet; 10.12.2014 в 11:19.
Stilet вне форума   Ответить с цитированием
Старый 13.12.2014, 01:17   #46
Stilet
Белик Виталий :)
Профессионал
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Адрес: Украина, Донецкая область, г. Краматорск
Сообщений: 57,842
Репутация: 6832
По умолчанию

Поиск подстроки в строке. FASM (32 бита)

Код:

format PE console
entry start
;http://www.programmersforum.ru/showpost.php?p=1448472&postcount=46
include 'D:\fasmw16726\INCLUDE\win32a.inc'
 
section '.data' data readable writeable
message db 'Привет мир',0
s db 'вет',0

section '.code' code readable executable

start:
  mov esi, message       ;Что искать
  mov edi, s             ;Где искать
  call pos               ;Вызываем функцию поиска
  ;Она вернет в ЕАХ номер символа, с которого начинается совпадение строки
  invoke ExitProcess,0   ;Это вызов корректного выхода из программы для Винды
  ret

; Тело функции поиска первого входящего
proc pos
 xor eax,eax   ;Очищаем регистры, с которыми будем работать при поиске - для возврата позиции
 xor ecx,ecx   ;Для просчета кол-ва пройденных символов в подстроке - длина подстроки по факту
 xor ebx,ebx   ;А это временный, куда будет поступать сравниваемый символ

 mov edx,edi   ;EDX нам понадобится для перескока в начало искомого, при несовпадении символов в поиске

 cmp byte [esi],0       ;Если конец исходной строки
 je exitproc            ;Выходим
 cmp byte [edi],0       ;Если конец искомой строки
 je exitproc            ;Тоже выходим

;Иначе начнем цикл поиска
for:
 inc eax                ;Увеличим счетчик позиции, на которой сравниваем символ
 mov bl,byte [esi]      ;Получим очередной сравниваемый символ
 cmp bl,[edi]           ;И сравним его с символом в искомой строке
 jne no                 ;Если символы не равны перескакиваем на следующий в исходной строке и заканчиваем сравнение блока
 inc ecx                ;Иначе увеличим счетчик длины искомого
 inc edi                ;Перескочим на следующий символ в искомой строке
 cmp byte [edi],0       ;И узнаем не конец ли искомого
 je exitproc            ;Если конец - строка найдена. Выходим.
 jmp nextiter           ;Иначе пойдем на следующую итерацию цикла поиска
no:
 sub esi,ecx            ;Поскольку используется один цикл для прохода
 ;После поиска подстроки нам приходится возвращаться на тот символ, с которого мы начали.
 ;Достигается это минусованием прошедших символов в искомом и текущей позиции в источнике
 xor ecx,ecx            ;Потом не забудим сбросить в ноль кол-во совпавших символов, раз они не найдены
 mov edi,edx            ;И переместиться в начало искомой строки для поиска с следующего символа
nextiter:
 inc esi                ;При каждой итерации будем перескакивать с символа на символ в исходной строке
 jmp for                ;И прыгать на следующий шаг цикла
exitproc:
 sub eax,ecx            ;Поскольку у нас ЕАХ будет указывать на позицию последнего символа искомого,
 ;Придется отнять от него длину искомого, чтоб получить позицию начинающуюся с нуля
 inc eax                ;А поскольку я не люблю когда начало идет с нуля - добавим единичку
 ;Чтоб найденная позиция выглядела по человечески
 ret
endp;

section '.idata' import data readable
library kernel,'kernel32.dll'
 
import kernel,\
       ExitProcess,'ExitProcess'

__________________
I'm learning to live...

Последний раз редактировалось Stilet; 13.12.2014 в 01:22.
Stilet вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа для шифрования раздела с виндой Жека90 Софт 1 12.06.2012 18:17
макрос для решения квадратных уравнений (перемещено из раздела Excel) sashkkk Помощь студентам 3 22.09.2010 23:06
Собираем команду для FAQ Aexx Свободное общение 112 14.10.2009 09:20
Формат по образцу для раздела... Busine2009 Microsoft Office Word 0 28.07.2009 08:05
Программа для копирования заданного раздела. С++ x007 Общие вопросы C/C++ 5 23.04.2009 23:52


07:59.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru