Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Другие темы раздела
Assembler this system does not support fullscreen mode https://www.cyberforum.ru/ assembler/ thread882161.html
this system does not support fullscreen mode В чем может быть ошибка?
Assembler Какое будет содержимое регистров после выполнения данного фрагмента программы
Уважаемые форумчане! Подскажите пожалуйста каково буде содержание регистра ECX в десятичном формате после выполнения следующей программы: MOV ECX,28 CLD MOV AL,100 ...
проверка оборудования Assembler
прошу помощи. напишите код с комментариями. заранее спасибо. для компьютера на своем рабочем столе определить: - тип компьютера; - версию MS-DOS; - число дисковых накопителей; - тип и число...
Assembler Ассемблер.повторное нажатие клавиши и использование таймера tasm Есть программа, в которой прорисовывается фигура и при нажатии любой клавиши должна начинаться смена цвета. Подскажите, пожалуйста, как сделать, чтобы при повторном нажатии той же клавиши или... https://www.cyberforum.ru/ assembler/ thread880292.html
Assembler Запрет на удаление файла https://www.cyberforum.ru/ assembler/ thread880013.html
Задача: Резидентная программа по горячей клавише выводит окно, в котором с помощью клавиш 'стрелка вверх' и 'стрелка вниз' выбирается режим работы с файлами, т.е. тип файлов, которые нельзя удалять....
Идентификация производителя монитора Assembler
Здравствуйте, не первый день пытаюсь найти способ узнать (идентифицировать) производителя монитора. Например (из аиды64): ID монитора SAM0691 Программу нужно написать на TASM, нашёл только...
Assembler Графика MASM
Помогите доделать! не могу понять почему движение фигуры происходит только наискось, а должна влево вправо вверх и вниз. вроде все правильно но не работает, помогите разобраться... data...
Assembler Часы вторым каналом таймера Надо запилить часы с помощью второго канала системного таймера, именно второго, не используя нулевой, с его перерыванием. Где то на просторах интернета, нарыл код, просто стартуем канал в режиме 3,... https://www.cyberforum.ru/ assembler/ thread877963.html
Assembler Связь ассемблера с Pascal https://www.cyberforum.ru/ assembler/ thread877335.html
Сформируйте массив, в котором соответствующий элемент является произведением элементов двух массивов. Помогитею.
Assembler Текстовый редактор - своя ОС Доброго времени суток. Задача: написать загрузчик, который выбирал бы либо unix(win) или свою ОС + написать свою ОС - текстовый редактор где можно заменять и удалять участки текста. Загрузчик:... https://www.cyberforum.ru/ assembler/ thread877212.html
Ушел с форума
Автор FAQ
14152 / 7040 / 827
Регистрация: 11.11.2010
Сообщений: 12,647
25.06.2013, 13:20  [ТС] 0

FAQ для раздела Assembler, MASM, TASM

25.06.2013, 13:20. Просмотров 104629. Ответов 64
Метки (Все метки)

Ответ

Поиск файлов и вывод содержимого каталога на экран. DOS
Поиск файлов в DOS реализуется, как правило, через функции 4Eh и 4Fh прерывания 21h. Эти функции позволяют обнаруживать в заданном каталоге или на заданном устройстве файлы с именами, соответствующими заданному образцу.
В DOS существует возможность обращаться к группе файлов, задав так называемую маску имени. При задании маски используются обозначения: ? - любой символ, * - любая группа символов. Например:
  • *.* - все файлы
  • *.СОМ - все файлы с расширением .СОМ
  • ?С.ЕХЕ - под ? понимается любая ОДНА буква, таким образом BC.EXE и NC.EXE удовлетворяют условию, а TCC.EXE - нет.
Функции 4h и 4Fh помещают результат своей работы в область передачи данных (DTA), организованную следующим образом:
Байты Содержимое
0 - 14h Зарезервировано
15h Атрибут
16h - 17h Время и дата файла
1Ah - 1Dh Размер файла
1Eh - 2Ah Имя файла
По умолчанию область DTA размещается в программе по адресу DS:80h, то есть там же, где и параметры командной строки. Для того, чтобы программа могла одновременно пользоваться и командной строкой и функциями поиска, часто применяется функция 1Ah прерывания 21h, предназначенная для перемещения области DTA в другое место памяти.
Приведем формат вызова функций поиска:
Код
AH:=4Eh       или          4Fh
    CX:=Атрибут файла
    DS:DX:= Адрес строки маски имени
Атрибут файла - это байт, определяющий внутренние характеристики файла:
БитНазваниеПереводЗначение
0 Read only Только для чтения в этот файл нельзя писать и его нельзя удалить
1 HiddenСкрытыйфайл скрывается от показа, пока явно не указано обратно
2 System Системный содержание файла критично для работы операционной системы
3 Label Метка тома  
4 Directory Каталогфайл, содержащий записи о входящих в него файлах. Каталоги могут содержать записи о других каталогах, образуя древовидную структуру
5 Archive Архивныйфайл изменен после резервного копирования или не был скопирован программами резервного копирования
6 Не используется 
7 Не используется 
8SharedРазделяемый (Novell NetWare)возможность одновременной работы с файлом в локальной вычислительной сети нескольким пользователям одновременно
Если в байте атрибутов установить бит 4 в 1, то функции поиска будут искать каталоги (которые с точки зрения DOS также являются файлами). При установленном бите 1 функции поиска обнаружат скрытые файлы, например в корневом каталоге диска С: файлы MSDOS.SYS и IO.SYS. Для поиска обычных файлов достаточно просто заказать нулевое значение байта атрибутов.
Приведем пример программы, ищущей и отображающей на экране имена всех файлов с расширением .СОМ в текущем каталоге:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
; masm dos com #
.286
.model tiny
.code
org    80h
; Область передачи данных по умолчанию
dta    db     15h dup (0)
attrib db     0
timdat dw     0
       dw     0
fsize  dd     0
fname  db     0Eh dup (0)
       org    100h
; Начало программы
start: mov    ah,4Eh; Ищем 1-й файл
       xor    cx,cx
       mov    dx,offset maska
       int    21h
       jc     net
povtor:mov    si,offset fname
pechat:lodsb; Печатаем имя
       test   al,al
       je     poisk
       int    29h
       jmp    pechat
poisk: mov    al,0Dh; Переводим строку
       int    29h
       mov    al,0Ah
       int    29h
       mov    ah,4Fh; Ищем следующий файл
       int    21h
       jnc    povtor
net:   ret    ; Файлов больше нет, конец
maska  db     '*.com',0; Маска для поиска
end start

Поиск файлов и вывод содержимого каталога на экран.
Используем системную команду DIR
Вывод списка файлов и подкаталогов из указанного каталога.
Код
DIR [диск:][путь][имя_файла] [/A[[:]атрибуты]] [/B] [/C] [/D] [/L] [/N]
  [/O[[:]порядок]] [/P] [/Q] [/S] [/T[[:]время]] [/W] [/X] [/4]
где [диск:][путь][имя_файла] Диск, каталог и/или файлы, которые следует включить в список.
/A Вывод файлов с указанными атрибутами.
 атрибуты
D Каталоги
R Доступные только для чтения
H Скрытые файлы
A Файлы для архивирования
S Системные файлы
  Префикс "-" имеет значение НЕ
/B Вывод только имен файлов.
/C Применение разделителя групп разрядов для вывода размеров файлов (по умолчанию). Для отключения этого режима служит ключ /-C.
/D Вывод списка в несколько столбцов с сортировкой по столбцам.
/L Использование нижнего регистра для имен файлов.
/N Отображение имен файлов в крайнем правом столбце.
/O Сортировка списка отображаемых файлов.
 порядок
N По имени (алфавитная)
S По размеру (сперва меньшие)
E По расширению (алфавитная)
D По дате (сперва более старые)
G Начать список с каталогов
Префикс "-" обращает порядок
/P Пауза после заполнения каждого экрана.
/Q Вывод сведений о владельце файла.
/S Вывод списка файлов из указанного каталога и его подкаталогов.
/T Выбор поля времени для отображения и сортировки
 время
C Создание
A Последнее использование
W Последнее изменение
/W Вывод списка в несколько столбцов.
/X Отображение коротких имен для файлов, чьи имена не соответствуют стандарту 8.3. Формат аналогичен выводу с ключом /N, но короткие имена файлов выводятся слева от длинных. Если короткого имени у файла нет, вместо него выводятся пробелы.
/4Вывод номера года в четырехзначном формате
Стандартный набор ключей можно записать в переменную среды DIRCMD. Для отмены
их действия введите в команде те же ключи с префиксом "-", например: /-W.
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
; masm dos com #
.286
.model tiny
.code
org 100h
start:  mov ah,4Ah  ;allow mem alloc.
    mov bx,10h  ;новый размер блока в параграфах
    int 21h     
    mov si,offset command_line
    int 2Eh ; execute a command using BASE LEVEL
    mov ah,4Ch  ;выходим из программы
    int 21h
command_line db N,'DIR',0Dh
N = $ - command_line - 1
end  start
или так
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
; masm dos com #
.286
.model tiny
.code
org 100h
start:  mov si,offset string    
    mov cx,N
@@: push cx
    lodsb
    mov ah,5      ;номер функции
    mov cl,al;передача параметра через регистр CL, содержимое CH=0 
    int 16h
    pop cx
    loop @b
    retn
string db 'DIR',0Dh; не более 15 символов
N = $ - string
end start
или так
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; masm dos com #
.286
.model tiny
.code
org 100h
start:  mov bx,100h     ;выделим блок памяти в 256 параграфов
        mov ah,4Ah               
        int 21h
        mov bx,offset parametrs ;указываем на блок параметров
        mov [bx+4],cs
        mov dx,offset filename
        mov ax,4B00h;загрузить и выполнить программу из командной строки
        int 21h
        retn        ;выход в DOS
command_line db N,'/c DIR',0Dh
N = $-command_line-1;длина командной строки
;командная строка типа pascal, начинается с байта длины строки, заканчивается
;ASCII-кодом клавиши Enter (0Dh). При передаче команды CMD.EXE нужно указать /С перед 
;строкой (требование вызова вторичного командного процессора). Программу cmd.exe
;из папки windows\system32\ проще разместить в том же каталоге, что и программа 
filename db 'cmd.exe',0
parametrs dw 0,command_line,5 dup(0);блок параметров
end start
или вот так
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
; masm dos com #
.286
.model tiny
.code
org     100h
start:  mov ah,4Ah      ;модифицируем назначенную память
        mov bx,100h     ;новый размер блока в параграфах
        int 21h         
        or bx,-1        ;требуемое число параметров для выполнения
        mov ah,48h      ;вделить блок памяти
        int 21h         ;возвращает в bx размер наибольшего доступного блока 
;памяти в параграфах
        mov ah,48h      ;вделить блок памяти, в bx действительно доступная память
        int 21h         ;возвращает в ах сегментный адрес выделенного блока
        mov es,ax       ;es:=new PSP
        mov ss,ax       ;ss:=new PSP
        xchg dx,ax      ;dx:=new PSP
        mov ah,26h      ;создать новый префикс программного сегмента
        int 21h         
        mov dx,offset filename
        mov di,80h      ;указатель на командную строку
        mov cx,(N+1)/2  ;копируем по два байта за раз, N округлен в большую 
;сторону к числу кратному два, поэтому добавочный movsb не нужен
        mov si,offset command_line
        rep movsw       ;создаем командную строку для запуска command.com
        mov ax,3D00h    ;открыть command.com на чтение
        int 21h
        xchg bx,ax      ;дескриптор файла в bx
        xor cx,cx       ;cx=dx=0
        xor dx,dx
        mov ax,4202h    ;установить файловый указатель на конец файла
        int 21h
        push ax         ;сохраним в стеке длину файла command.com
        mov ax,4200h    ;установить файловый указатель на начало файла
        int 21h
        mov dx,es       ;пересчитываем чему должен быть равен dx из расчета,
        add dx,10h      ;что cs*10h+dx=es*10h+100h
        mov cx,cs
        sub dx,cx
        shl dx,4        ;в dx адрес буфера, куда будет скопирован command.com
        pop cx          ;в сх число байтов для чтения 
        mov ah,3Fh      ;читаем command.com в буфер
        int 21h
        mov ah,3Eh      ;закрыть файл command.com
        int 21h
        mov ax,es       ;ds:=new PSP
        mov ds,ax       ;при старте СОМ-файла cs=ds=es=ss=PSP ip=100h
        push es         ;новое значение cs:=new PSP
        push 100h       ;новое значение ip:=100h
        retf            ;запускаем command.com для создания файла myfile.txt
filename db 'c:\windows\system32\command.com',0;полный путь к command.com
command_line db N-1,'/c DIR',0Dh
N = $ - command_line
db 0; если N нечетное, то копируется и добавочный нулевой символ 
end     start

Поиск файлов и вывод содержимого каталога на экран. Windows
Пример из книги Пирогова "Ассемблер для Windows". Программа осуществляет поиск в указанном или текущем каталоге. Поиск проходит по дереву каталогов, начиная с заданного
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
; masm windows console #
.686
.model flat
include \masm32\include\windows.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;объявление используемых функций Windows (внешние ссылки)
extern _imp__wsprintfA:dword
extern _imp__CharToOemA@8:dword;
extern _imp__GetStdHandle@4:dword;
extern _imp__WriteConsoleA@20:dword;
extern _imp__ReadConsoleA@20:dword;
extern _imp__ExitProcess@4:dword;
extern _imp__GetCommandLineA@0:dword;
extern _imp__lstrcat@8:dword;
extern _imp__lstrcpyA@8:dword;
extern _imp__FindFirstFileA@8:dword;
extern _imp__FindNextFileA@8:dword;
extern _imp__FindClose@4:dword;
extern _imp__lstrlenA@4:dword
_FIND STRUC;структура, используемая для поиска файлов при помощи
;функций FindFirstFileA и FindNextFileA
ATR     dd ?;атрибут файла
CRTIME  dd ?;время создания файла
        dd ?
ACTIME  dd ?;время доступа к файлу
    dd ?    
WRTIME  dd ?;время модификации файла
    dd ?
SIZEH   dd ?;размер файла
SIZEL     dd ?
    dd ?;резерв
    dd ?
NAM db 260 dup(0);длинное имя файла
ANAM db 14 dup(0);короткое имя файла
_FIND ENDS
.code
start:   push STD_INPUT_HANDLE
         call _imp__GetStdHandle@4;получаем HANDL1 для ввода
         mov HANDL1,eax
         push STD_OUTPUT_HANDLE
         call _imp__GetStdHandle@4;получаем HANDL для вывода
         mov HANDL,eax
         call NUMPAR ;получить количество параметров
     mov PAR,eax
     dec eax;если параметр один, то искать в текущем каталоге
     je NO_PAR
     mov edx,2;получить параметр номером edi
     lea ebx,BUF
     call GETPAR
     jb NO_PAR
         mov edi,3;подключить параметр - маску поиска
     lea ebx,MASKA
     call GETPAR
NO_PAR:  push offset BUFER
     call FIND
     push NUMF;вывести количество файлов
     push offset FORM
     push offset BUFER
     call _imp__wsprintfA
         add esp,12
     lea eax,BUFER
     mov edi,1
     call WRITE
     push NUMD;вывести количество каталогов
     push offset FORM1
     push offset BUFER
     call _imp__wsprintfA
         add esp,12
     lea eax,BUFER
     mov edi,1
     call WRITE
_END:    push 0
         call _imp__ExitProcess@4
;---------------------------------------------------------------
WRITE PROC;вывести строку с переводом строки
     push eax
         push eax
     call _imp__lstrlenA@4;получить длину параметра
     pop ebx
     mov dword ptr [ebx+eax],0D0Ah
     add eax,2
NO_ENT:  push 0;резерв
     push offset LENS;выведено символов
     push eax;длина строки
     push ebx;адрес строки
     push HANDL;HANDL вывода
         call _imp__WriteConsoleA@20;вывести строку 
         RET
WRITE ENDP
;-------------------------------------------------
NUMPAR PROC;определение параметров в командной строке
    call _imp__GetCommandLineA@0
    mov esi,eax
    xor ecx,ecx
    mov edx,1
L1: cmp byte ptr [esi],0
    je L4
        cmp byte ptr [esi],32
    je L3
    add ecx,edx;номер параметра
        xor edx,edx
    jmp L2
L3: or edx,1
L2: inc esi
    jmp L1
L4: mov eax,ecx
    ret
NUMPAR ENDP
;------------------------------------------------------
GETPAR PROC;в edi указатель на буфер, куда помещен параметр
;в ebx номер параметра
        call _imp__GetCommandLineA@0
    mov esi,eax
    xor ecx,ecx
    mov edx,1
L10:    cmp byte ptr [esi],0
    je L40
        cmp byte ptr [esi],32
    je L30
    add ecx,edx;номер параметра
        xor edx,edx
    jmp L20
L30:    or edx,1
L20:    cmp ecx,edi
    jne L50
        mov al,[esi]
    mov [ebx],al
    inc ebx
L50:    inc esi
    jmp L10
L40:    mov byte ptr [ebx],0
    ret
GETPAR ENDP
FIND PROC;поиск в каталоге файлов и вывод имени каталога в BUF
FINDH   equ [ebp-4]
DIRS    equ [ebp-304]
DIRSS   equ [ebp-604]
DIRV    equ [ebp-904]
DIR equ [ebp+8]
    enter 904,0
    xor eax,eax
    lea edi,DIRV
    mov ecx,900/4
    rep stosd
    push DIR
    call _imp__lstrlenA@4
    mov ebx,eax
    mov edi,DIR
    cmp byte ptr [edi],0
    je _OK
    cmp byte ptr [edi+ebx-1],'\'
    je _OK
        push offset AP
    push DIR
    call _imp__lstrcat@8
_OK:    push DIR
    lea eax,DIRSS
    push eax
    call _imp__lstrcpyA@8
    push offset MASKA;путь с маской
    push DIR
    call _imp__lstrcat@8
        push offset FIN;здесь начало поиска
    push DIR
    call _imp__FindFirstFileA@8
    inc eax;cmp eax,-1
    je _ERR
    dec eax
    mov FINDH,eax;сохранить дескриптор поиска
LF: cmp byte ptr FIN.NAM,".";исключить файлы "." и ".."
    je _FF
    lea eax,DIRSS
    push eax
    lea eax,DIRS
    push eax
    call _imp__lstrcpyA@8
        push offset FIN.NAM
    lea eax,DIRS
        push eax
    call _imp__lstrcat@8
    test byte ptr FIN.ATR,10h;не каталог ли?
    je NO_DIR
    push offset DIRN
    lea eax,DIRS
        push eax
    call _imp__lstrcat@8
        inc NUMD
    dec NUMF
    mov PRIZN,1
    lea eax,DIRS
    push eax
    call OUTF
    jmp _NO
NO_DIR: lea eax,DIRS
    push eax
    call OUTF
    mov PRIZN,0
_NO:    cmp PRIZN,0
        jz _F
        lea eax,DIRSS
    push eax
    lea eax,DIRV
    push eax
    call _imp__lstrcpyA@8
    push offset FIN.NAM
    lea eax,DIRV
    push eax
    call _imp__lstrcat@8
    lea eax,DIRV
    push eax
    call FIND
_F: inc NUMF
_FF:    push offset FIN
    push FINDH
    call _imp__FindNextFileA@8;продолжение поиска
    test eax,eax;cmp eax,0
    jne LF
    push FINDH
    call _imp__FindClose@4;закрыть поиск
_ERR:   leave
    ret 4
FIND ENDP
OUTF proc
STRN    equ [ebp+8]
    push ebp
    mov ebp,esp
    push STRN
    push STRN
    call _imp__CharToOemA@8;преобразовать строку
    mov eax,STRN
    mov edi,1
    call WRITE;здесь вывод результата
    inc NUM
    cmp NUM,22;конец страницы?
    jne NO
    mov NUM,0
    mov edi,1
    lea eax,TEXT
    call WRITE;ждать вывод строки
    push 0
    push offset LENS
    push 10
    push offset BUFIN
    push HANDL1
    call _imp__ReadConsoleA@20
NO: pop ebp
    ret 4
OUTF endp
;data------------------------------------------
BUF     db 0
    db 100 dup (?)
LENS    dd 100;количество выведенных символов
HANDL   dd ?
HANDL1  dd ?
MASKA   db "*.*",0
AP  db "\",0
FIN _FIND <0>
TEXT    db '„«п Їа®¤®«¦Ґ*Ёп **¦¬ЁвҐ Є«*ўЁиг ENTER',13,10,0;"Нажмите клавишу Enter" в кодировке CP-866
BUFIN   db 10 dup(0)
NUM db 0
NUMF    dd 0;счетчик файлов
NUMD    dd 0;счетчик каталогов
FORM    db '—Ёб«® **©¤Ґ*ле д*©«®ў: %lu',0;"Число найденных файлов"
FORM1   db '—Ёб«® **©¤Ґ*ле Є*в*«®Ј®ў: %lu',0;"Число найденных каталогов"
BUFER   db 100 dup(0)
DIRN    db " <DIR>",0
PAR     dd 0;количество параметров
PRIZN   db 0      
end start


Вернуться к обсуждению:
FAQ для раздела Assembler, MASM, TASM
6
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.06.2013, 13:20

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Есть ли компиляторы Tasm или Masm для 64-разрядных систем
Есть ли компиляторы Tasm или Masm для 64-разрядной с-мы??? если есть просьба скинуть...

MASM, TASM, FASM: что выбрать для программирования в ядре
Какой асемлер выбрать для проганья в едре? вынь

Подскажите ссылки на FAQ для разделов Assembler, MASM, TASM
Скиньте FAQ для разделов Assembler,MASM,TASM где много вариантов &quot;Hello,world!$&quot; и где написана...

Подскажите этот код для TASM или MASM?
Подскажите это TASM или MASM? EOFLINE EQU '$' AStack SEGMENT STACK DW 12 DUP(?) AStack ENDS...

Где скачать TASM или MASM для Win 10 64 разряда
Где скачать TASM или MASM для Win 10 64 разряда ???? Хочу выучить ассемблер не не знаю где скачать...

Не работает пример из FAQ для раздела – “C# для начинающих”
Фак здесь - https://www.cyberforum.ru/csharp-beginners/thread163620.html первый же пример не...

0
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.