project
A DOS® Server In a Virtual Machine
|
An Assembly Language
This article is primarily dedicated to an Assembler for Linux.
I chose The Netwide Assembler (also known as "NASM"). But I've been confronted with difficulties since then.
I'm scarce of knowledge of programming in the Assembly language under Linux.
Table Of Contents:
"Hello World" under DOS
|
NASM |
TASM |
COM |
; This example is compiled into a COM
; It is written in NASM.
; Copyleft 2014 Artem Efremov
org 100h
section .text
start:
mov AH, 09h
lea DX, [CS:msg]
int 21h
mov AX, 4C00h; Errorlevel = 0
int 21h
section .data
msg DB "Hello World", 0Dh, 0Ah, "$"
section .bss
; uninitialized data here
|
; This example is compiled into a COM
; It is written in TASM.
; Copyleft 2014 Artem Efremov
.model tiny
code segment
assume CS:code, DS:code
org 100h
start:
mov AH, 09h
lea DX, [CS:msg]
int 21h
mov AX, 4C00h; Errorlevel = 0
int 21h
msg DB "Hello World", 0Dh, 0Ah, "$"
code ends
end start
|
EXE |
; This example is compiled into an EXE
; It is written in NASM.
; Copyleft 2014 Artem Efremov
segment code
..start:
mov AX, data
mov DS, AX
; mov AX, stack
; mov SS, AX
; mov SP, stacktop
lea DX, [DS:msg]
mov AH, 09h
int 21h
mov AX, 4C00h
int 21h
segment data
msg:
DB "Hello World", 0Dh, 0Ah, "$"
segment stack stack
resb 256
stacktop:
|
; This example is compiled into an EXE
; It is written in TASM.
; Copyleft 2014 Artem Efremov
text segment
assume CS:text, DS:data
start:
mov AX, data
mov DS, AX
lea DX, [DS:msg]
mov AH, 09h
int 21h
mov AX, 4C00h; Errorlevel = 0
int 21h
text ends
data segment
msg DB "Hello World", 0Dh, 0Ah, "$"
data ends
stk segment stack
DB 256 DUP(0)
ends
end start
|
"Hello World" under Linux
; http://www.int80h.org/bsdasm/#system-calls
; nasm -f elf hello2.asm && ld -s -o hello2 hello2.o
%include "system.inc"; Asmutils is required
section .data
hello DB "Hello, World!", 0Ah
hbytes EQU hello
section .text
global _start
_start:
push dword hbytes
push dword hello
push dword stdout
sys.write
push dword 0
sys.exit
nasm -f elf hello.asm && ld -s -o hello hello.o
[Download Asmutils]
An Input under Linux
; This example demonstrates using Linux/i386 system calls by example of a user's input
; Written in NASM.
; by Artem V. Efremov (also known as "Nikodim")
;
; Some useful information is available at:
; http://www.ibm.com/developerworks/ru/library/l-gas-nasm/index.html
; http://www.nasm.us
; http://www.unusedino.de/linuxassembly/syscall.html
; parameters: EBX, ECX, EDX, ESI, EDI (for Linux kernel, ver. 2.4+), EBP
; returned code: EAX
buffersize EQU 1024; the buffer's size (in bytes)
section .text
global _start
_start:
lea ECX, [DS:welcome]
mov EDX, welcome_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
begin:
mov AL, 0; ASCII(0)
push AX; parameter passing
call NEAR zerofilling; initializing the buffer
pop AX
lea ECX, [DS:prompt]
mov EDX, prompt_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
; sys_read: ssize_t sys_read(unsigned int fd, char * buf, size_t count)
mov EAX, 3; sys_read
mov EBX, 1
lea ECX, [DS:buffer]; offset
mov EDX, buffer_len
int 80h
call NEAR buffer_reckoning; reckoning the actual buffer's length
lea ECX, [DS:msgbefore]
mov EDX, msgbefore_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
lea ECX, [DS:buffer]
mov EDX, [DS:buffer_act_len]
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
lea ECX, [DS:endl]
mov EDX, endl_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
; the "say" command
lea EDI, [DS:cmd_say]; the command's offset
mov EAX, cmd_say_len
push EAX
push EDI
call NEAR check_for_equality
pop EDI
pop EAX
cmp ECX, 0; comparing whether the two strings are equal to each other
jnz next_check_02
lea ECX, [DS:say]
mov EDX, say_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
next_check_02:
; the "exit" command
lea EDI, [DS:cmd_exit]; the command's offset
mov EAX, cmd_exit_len
push EAX
push EDI
call NEAR check_for_equality
pop EDI
pop EAX
cmp ECX, 0; comparing whether the two strings are equal to each other
jnz begin; returning if not "exit"
; a quit message
lea ECX, [DS:endline]
mov EDX, endline_len
push EDX; parameter passing
push ECX; parameter passing
call NEAR printIt
pop ECX
pop EDX
; sys_exit: int sys_exit(int status)
mov EAX, 1; sys_exit
mov EBX, 0; status = 0
int 80h
printIt:
push EBP
push ECX
push EDX
push EAX
push EBX
mov EBP, ESP
; sys_write: ssize_t sys_write(unsigned int fd, const char * buf, size_t count)
mov EAX, 4; sys_write
mov EBX, 1
mov ECX, [SS:EBP + 4 + 4 + 4 + 4 + 4 + 4]; EBX + EAX + EDX + ECX + EBP + EIP
mov EDX, [SS:EBP + 4 + 4 + 4 + 4 + 4 + 4 + 4]; EBX + EAX + EDX + ECX + EBP + EIP
int 80h
pop EBX
pop EAX
pop EDX
pop ECX
pop EBP
retn
zerofilling:
; zerofilling
push EBP
push ECX
push EDX
push AX
mov EBP, ESP
mov AX, [SS:EBP + 2 + 4 + 4 + 4 + 4]; AX + EDX + ECX + EBP + EIP
mov ECX, buffer_len; setting the counter
lea EDX, [DS:buffer]
loop_01:
mov BYTE [DS:EDX + ECX - 1], AL; ASCII(0)
loop loop_01
pop AX
pop EDX
pop ECX
pop EBP
retn
buffer_reckoning:
push ECX
push ESI
push AX
pushf
; reckoning the actual buffer's length
cld; clearing the DF flag (forward direction)
mov ECX, 0; ECX = 0
lea ESI, [DS:buffer]
loop_02:
lodsb
cmp AL, 0
jz next_step_01
inc ECX; ECX++
jmp SHORT loop_02
next_step_01:
mov [DS:buffer_act_len], ECX
popf
pop AX
pop ESI
pop ECX
retn
check_for_equality:
; checking for a command in the list
; (returns: ECX = 0 if true; otherwise, false)
push EBP
pushfd
push ESI
push EDI
mov EBP, ESP
cld
mov CX, DS
mov ES, CX
lea ESI, [DS:buffer]; the buffer: [DS:ESI]
mov EDI, [SS:EBP + 4 + 4 + 4 + 4 + 4]; the command's offset: [ES:EDI]
mov ECX, [SS:EBP + 4 + 4 + 4 + 4 + 4 + 4]
repe cmpsb; comparing the two strings
pop EDI
pop ESI
popfd
pop EBP
retn
section .data
welcome: DB 0Dh, 0Ah, "*** An Input Utility for Linux/i386", 0Ah
DB "This has been written by Artem V. Efremov (also known as 'Nikodim') in The Netwide Assembler.", 0Ah
DB "http://vm.ru54.com/asm/", 0Ah
DB "You may use the program for evaluation purpose, modify the code.", 0Ah
DB "Type 'exit' to quit. Type 'say' to say 'Hello' everybody. Type something just for fun.", 0Dh, 0Ah
welcome_len EQU $ - welcome
prompt: DB 0Dh, 0Ah, "Type something> "
prompt_len EQU $ - prompt
endl: DB 0Dh, 0Ah; "\n"
endl_len EQU $ - endl
endline: DB 0Dh, 0Ah, "Exiting...", 0Dh, 0Ah
endline_len EQU $ - endline
msgbefore: DB 0Dh, 0Ah, "You have typed: "
msgbefore_len EQU $ - msgbefore
buffer_act_len: DD 0; actual length of the buffer
buffer: TIMES buffersize DB "E"; buffer
buffer_len EQU $ - buffer
DB 0; ASCII(0): the end of the buffer
; commands:
cmd_exit: DB "exit"
cmd_exit_len EQU $ - cmd_exit
cmd_say: DB "say"
cmd_say_len EQU $ - cmd_say
say: DB 0Dh, 0Ah, "Hello there! :)", 0Dh, 0Ah
say_len EQU $ - say
section .bss
; uninitialized data
section .stack
Reboot
; This program reboots a Linux/i386 system for no reason.
; Written in NASM.
; by Artem V. Efremov (also known as "Nikodim")
;
; kernel/sys.c
; int reboot(int magic1, int magic2, int cmd, void *arg);
;
; Some useful information is available at:
; http://man.he.net/man2/reboot
; http://www.ibm.com/developerworks/ru/library/l-gas-nasm/index.html
; http://www.nasm.us
; http://www.unusedino.de/linuxassembly/syscall.html
; parameters: EBX, ECX, EDX, ESI, EDI (for Linux kernel, ver. 2.4+), EBP
; returned code: EAX
section .text
global _start
_start:
call NEAR reboot
; sys_exit: int sys_exit(int status)
mov EAX, 1; sys_exit
mov EBX, 0; status = 0
int 80h
reboot:
push EAX
push EBX
push ECX
push EDX
push ESI
; http://man.he.net/man2/reboot
; int reboot(int magic1, int magic2, int cmd, void *arg);
mov EAX, 88; sys_reboot
mov EBX, 0xfee1dead; magic1 = 0xfee1dead (LINUX_REBOOT_MAGIC1)
mov ECX, 672274793; magic2 = 672274793 (LINUX_REBOOT_MAGIC2)
mov EDX, 0x1234567; cmd = 0x1234567 (LINUX_REBOOT_CMD_RESTART)
mov ESI, 0; *arg = 0
int 80h
pop ESI
pop EDX
pop ECX
pop EBX
pop EAX
retn
section .data
section .bss
; uninitialized data
section .stack
Useful Links
|
|