АССЕМБЛЕР! (Обучение в виде чтения топика)

Автор: proninraw, 2026-09-21 20:24

Назад

❤ 1
[проверен] — 2026-09-21 20:24

Урок 1!

Я буду писать в этой теме каждый день (и при возможности) обучение языку ассемблер. 32-битный, но он вполне подойдет под 64 битный с нюансами, например, сейчас расскажу про тот случай, когда нужно применять костыль в одно слово в одну строчку, чтобы код не упал. Если в eax лежало отрицательное число, просто так сменить eax на rax нельзя. Для того, чтобы это решить, просто сделайте так:

mov eax, -5     ; задаем регистру EAX отриц значение -5, записывается как 0xFFFFFFFB
cdqe            ; Теперь rax = 0xFFFFFFFFFFFFFFFB (честные 64-битные -5)
add rax, 10     ; Корректно прибавит 10, получим 5

Если вы ничего не поняли - то тут и нет стремления понять. Просто помните про cdqe и держите это в уме! (P.S работа рассчитана на x86, но будет работать на x64. пишется под Linux)

Hello, World!

В разделе .text мы указываем ядру, с какого места начать выполнение, передав ему глобальную метку _start:, обозначающую точку входа программы. В секции .data мы создаем переменную msg, задаем ей дерективу db (Define Byte - 8 бит; Символы строк, флаги (0/1), числа 0–255) В разделе .text мы указываем ядру, с какого места начать выполнение, передав ему глобальную метку _start:, обозначающую точку входа программы.

SECTION .data
msg db 'Hello, world', 0Ah ; 0Ah - аналог \n

SECTION .text
global _start

_start: 

         ; sys_write, т.е запись данных в ОЗУ 
    mov edx, 13 ; кол-во сиволов в msg + \n (1 символ)
    mov ecx, msg ; адрес строки
    mov ebx, 1 ; куда пишем - в stdout, т.е в терминал проще говоря 
    mov eax, 4 ; вызываем sys_write, запись данных
    int 80h ; передаем управление ядру Linux

        ; если мы не напишем код ниже, то код заработает но выплюнет ошибку сегментации
    mov ebx, 0 ; sys_exit, выход из программы
    mov eax, 1 ; завершаем программу со статусом 0, т.е "Ошибок нет".
    int 80h ; передаем управление ядру

Расписал как мог. Надеюсь, вы всё поняли. Ждите второго урока, а вопросы пишите сюда же!

❤ 0
[проверен] — 2026-09-21 20:25

Не рекомендую в слепую CTRL+C, CTRL+V копировать кож. Пишите его вручную.

❤ 0
[проверен] — 2026-09-21 20:29

Забыл:

~$ nasm -f elf helloworld.asm
~$ ld -m elf_i386 helloworld.o -o helloworld
~$ ./helloworld

Вот так компиляция идёт UPD: Это компилирует 32-битное приложение. Если вы попытаетесь собирать под 64-битный elf64, пихать туда cdqe или чередовать бездумно eax с rax, то у вас компиляция упадёт. Но не волнуйтесь — x86_64 по своей логике не сильно отличается. Я просто привык к классическим 32-битным регистрам (eax, ecx и т.д.), с них и начнем.

❤ 0
[проверен] — 2026-09-21 20:55

ухты, полезненько! буду наблюдать :3

❤ 1
[проверен] — 2026-09-22 10:41

Урок 2: подпрограммы

Если отупить – подпрограммы это функции, к которым мы переключаемся через jmp (jump; перейти/прыгнуть к чему-либо)

SECTION .data
msg db "Hello, World", 0Ah
msg1 db "Cute boy!", 0Ah
SECTION .text 
global _start

_start:

first: 
    mov edx, 13
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 80h

    mov ebx, 0
    mov eax, 1
    int 80h

    jmp two

two:
    mov edx, 
    mov ecx, msg1
    mov ebx, 1
    mov eax, 4
    int 80h

    mov ebx, 0
    mov eax, 1
    int 80h

Привычный с первого урока нам код внезапно оброс first и two. first - функция, которая выполняется первой потому что… Она стоит самой первой. Ко two вы уже переходим через jmp, при этом в first если мы напишем:

mov ebx, 0
mov eax, 1

jmp two

То переход к two не начнётся, ибо mov eax, 1 говорит ядру, что надо выполнят syscall_exit, т.е закончить программу. Заканчиваем мы её и выводим код выполнения 0 “Успешно” только в подпрограмме two.

❤ 1
[проверен] — 2026-09-22 10:55

А для отступов можно что угодно использовать? Или только TAB? Или только пробелы?

❤ 2
[проверен] — 2026-09-22 15:23

можно хоть пробелы хоть TAB, а можно ваще без них, похрен вообще

Чтобы ответить, войдите.