Как оболочка считывает команды | Создание токенизатора на ассемблере
Mxy
0:00 / 0:00
Как оболочка считывает команды | Создание токенизатора на ассемблере
4 089 просмотров · 10 мес. назад
Mxy
13 тыс. подписчиков
4 089 просмотров · 10 мес. назад
Следите за мной в x64Playground: https://x64.halb.it (Выберите GNU в качестве ассемблера!)
Посмотрите курс с самого начала: • Learn Assembly For Beginners | Introductio...
Следующее видео в курсе: • How Strings Are Compared in Assembly | Beg...
Предыдущее видео в курсе: • Arrays in Assembly | Beginner Tutorial | L...
00:00 Как оболочки считывают команды
03:10 Как работает токенизация
06:15 Как просмотреть память в x64Playground
09:50 Написание функции токенизации
13:05 Поиск конца слов
17:26 Создание массива токенов
18:05 Аномальная функция, которая повреждает нашу память!
19:40 Функция пропуска пустого пространства
23:18 Остановка функции "блуждающей черной дыры"
28:20 Печать строкового массива (печать токенов)
32:42 Функция println на ассемблере (неэффективная, но работает!)
33:40 Дополнительное тестирование и некоторые граничные случаи
;## Наши функции для копирования и вставки. Ниже приведена ПОЛНАЯ ПРОГРАММА, если вы хотите протестировать ее, не написав ее самостоятельно.
; Выход:
хор рди, рди
Мов Ракс, 60 лет
системный вызов
распечатать:
нажать РДИ
позвони Слену
поп-рси
мов рдкс, ракс
мов ракс, 1
мов РДИ, 1
системный вызов
в отставку
Слен:
xor rcx, rcx
slen.loop:
мов аль, [rdi + rcx]
cmp al, 0
я слен.рет
Inc RCX
jmp slen.loop
слен.рет:
мов ракс, rcx
в отставку
читать строку:
мов rdx, рси
мов рси, рди
мов ракс, 0
мов рди, 0
системный вызов
в отставку
;######
;### ПОЛНАЯ ПРОГРАММА НИЖЕ ######
.intel_syntax noprefix
.global _start
.text
_start:
lea rdi, [buf]
lea rsi, [bufsize - 1]
call readline
cmp rax, 0
je nodata
lea rdi, [buf]
mov byte ptr [rdi + rax], 0
call memview
lea rdi, [buf]
lea rsi, [tokens]
call tokenize
int3
call print_tokens
call memview
call exit
nodata:
lea rdi, [s_nodata]
call print
call exit
print_tokens:
lea r15, [tokens]
pt.loop:
mov rdi, [r15]
cmp rdi, 0
je pt.end
call println
add r15, 8
jmp pt.loop
pt.end:
ret
tokenize:
mov r15, rsi
tokenize.loop:
call skipwhite
cmp byte ptr [rdi], 0x0
je tokenize.end
mov [r15], rdi
add r15, 8
call memview
call findend
cmp byte ptr [rdi], 0
je tokenize.end
mov byte ptr [rdi], 0
inc rdi
call memview
jmp tokenize.loop
tokenize.end:
ret
findend:
cmp byte ptr [rdi], ' '
je findend.ret
cmp byte ptr [rdi], 0
je findend.ret
inc rdi
jmp findend
findend.ret:
ret
skipwhite:
cmp byte ptr [rdi], ' '
je skipwhite.advance
ret
skipwhite.advance:
inc rdi
jmp skipwhite
exit:
xor rdi, rdi
mov rax, 60
syscall
print:
push rdi
call slen
pop rsi
mov rdx, rax
mov rax, 1
mov rdi, 1
syscall
ret
println:
push rdi
call slen
pop rsi
mov rdx, rax
mov rax, 1
mov rdi, 1
syscall
mov rax, 1
mov rdi, 1
lea rsi, [newline]
mov rdx, 1
syscall
ret
slen:
xor rcx, RCX
slen.loop:
мов аль, [rdi + rcx]
cmp al, 0
я слен.рет
Inc RCX
jmp slen.loop
слен.рет:
мов ракс, rcx
в отставку
читать строку:
мов rdx, рси
мов рси, рди
мов ракс, 0
мов рди, 0
системный вызов
в отставку
мемвью:
мов р14, рсп
леа рсп, [буф]
int3
мов рсп, r14
в отставку
.данные
буф: .skip 128 ;# 4096
размер буфера = . - buf
tokens: .skip 128
newline: .byte '\n'
s_nodata: .asciz "\nДанные не введены!\n"
:#######