Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.12.2014, 09:51   #41
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

  • Графика 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, 09:58   #42
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

  • Код:
    ; пример 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 в 10:09.
Mikl___ вне форума Ответить с цитированием
Старый 05.12.2014, 10:09   #43
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

  • под 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 в 10:43.
Mikl___ вне форума Ответить с цитированием
Старый 05.12.2014, 11:01   #44
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,139
По умолчанию

Графика 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, 11:35   #45
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

На всяки случай и я кое-что подброшу.
Ввод и вывод числа в 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 в 10:19.
Stilet вне форума Ответить с цитированием
Старый 13.12.2014, 00:17   #46
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Поиск подстроки в строке. 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 в 00:22.
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программа для шифрования раздела с виндой Жека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