logo

eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

Unnamed repository; edit this file 'description' to name the repository.
commit: f3bb29739dce70badebf121c322c1374292c4c7a
parent e7b0fe83ce6f56f0c4838c7ed3c8d5d091170666
Author: LinuxMercedes <LinuxMercedes@gmail.com>
Date:   Tue, 11 Dec 2018 14:47:56 -0600

Merge pull request #465 from PoroCYon/eeeeeeeeeeeeeeeeeeeeeeee

Add/improve some assembly versions

Diffstat:

Me.asm63+++++++++++++++++++++++++++++++++++++++++++++++++++------------
Ae.linux.arm.S36++++++++++++++++++++++++++++++++++++
Ae.mbr.asm31+++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+), 12 deletions(-)

diff --git a/e.asm b/e.asm @@ -1,17 +1,56 @@ +; compile with: +; $ [ny]asm -felf(32|64) -oe.o e.asm +; $ (gcc|clang) -m(32|64) -oe e.o -nostdlib -nostartfiles + section .text -global _start +global _start + +%if __BITS__ == 32 +%define r(n) e%+n +%define SYS_write 4 +%define rarg0 ebx +%define rarg1 ecx +%define rarg2 edx +%define syscall int 0x80 +%else +%define r(n) r%+n +%define SYS_write 1 +%define rarg0 rdi +%define rarg1 rsi +%define rarg2 rdx +default rel +%endif + +; size of a Linux pipe buffer +%define PIPE_SIZE 0x10000 +%define STDOUT_FILENO 1 + +; Instead of simply storing a char in .rodata and write(2)-ing it +; over and over again, we first fill a buffer full of e's, and *then* +; write the entire buffer. This is much faster than the first option, +; because we only need to issue a syscall once every 65536 bytes. (Remember +; that doing a syscall requires the kernel to handle an interrupt etc etc etc.) -_start: +_start: + ; allocate space for the message + mov r(cx), PIPE_SIZE + mov r(bx), r(cx) ; we'll need it later + sub r(sp), r(cx) - mov rax, 1 - mov rdi, 1 - mov rsi, msg - mov rdx, len - loop: - syscall - jmp loop + ; quick memset(3) + mov al, 'e' + mov r(di), r(sp) + rep stosb -section .data + ; push+pop is actually a smaller encoding than mov for ints that fit within 8 bit + push STDOUT_FILENO + pop rarg0 + mov rarg1, r(sp) + mov rarg2, r(bx) -msg: db "e" -len: equ $ - msg +.loop: + ; set this within the loop because the syscall's exit code is placed in r(ax) + push SYS_write + pop r(ax) + syscall + jmp short .loop diff --git a/e.linux.arm.S b/e.linux.arm.S @@ -0,0 +1,36 @@ +#define SYS_write 4 +#define STDOUT 1 +#define PIPE_SIZE 0x10000 + +.arm +.align 4 + +.section .text, "ax", %progbits + +type _start, %function +globl _start +_start: + mov r1, #PIPE_SIZE + + ldr r3, =('e'|('e'<<8)|('e'<<16)|('e'<<24)) + mov r4, r3 + mov r5, r3 + mov r6, r3 + +.Lloop: + push {r3-r6} + sub r1, #(4*4) + cmp r1, #0 + bgt .Lloop + + mov r7, #SYS_write + mov r1, sp + mov r2, #PIPE_SIZE + +.Lcall: + mov r0, #STDIN + swi #0 + b .Lcall + +.align 4 +.pool diff --git a/e.mbr.asm b/e.mbr.asm @@ -0,0 +1,31 @@ +bits 16 +org 0x7C00 + +_start: + ; enable cursor + xor cx, cx + mov ch, 00100000b + mov ah, 1 + int 0x10 + + ; move cursor to top + xor dx, dx + xor bx, bx + inc ah + int 0x10 + + ; print 1 char + mov ax, 'e'|(0x0E<<8) + .loop: + int 0x10 + jmp short .loop + +END: + times 0x200-2-(END-_start) db 'e' + db 0x55,0xAA + +stack: + +%if END-_org > 0x200-2 +%error "Not enough space!" +%endif