Files
solutions/04-addr-methods/task2.asm

130 lines
2.9 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

global main
extern printf
struc timespec ; структура, в которой линукс хранит время. Тут нужна для удобства в будущем
.tv_sec: resq 1
.tv_nsec: resq 1
endstruc
%include "timer.inc"
section .note.GNU-stack
section .data
example: times 128 db 127
section .bss
; uses timespec model
start: resq 2
finish: resq 2
deltatime: resq 2
section .text
%macro PUSH_M 1-*
%rep %0
push %1
%rotate 1
%endrep
%endmacro
%macro RPOP_M 1-*
%rotate -1
%rep %0
pop %1
%rotate -1
%endrep
%endmacro
%define CLOCK_REALTIME 0
%macro TIME_1_000_000 0-1+ ; принимает команду, которую будет пытаться обмерить по времени
PUSH_M rax, rdi, rsi, rcx
mov rax, 228 ; Время начала
mov rdi, CLOCK_REALTIME
mov rsi, start
syscall
RPOP_M rax, rdi, rsi, rcx
mov rcx, 1000000000 ; выполняем миллион раз
%%loop:
%1
loop %%loop
PUSH_M rax, rdi, rsi, rcx
mov rax, 228 ; Время конца
mov rdi, CLOCK_REALTIME
mov rsi, finish
syscall
RPOP_M rax, rdi, rsi, rcx
; считаем секунды
push rax ; можно было бы оптимизировать, но мне лень макросы переписывать
mov rax, [finish + timespec.tv_sec]
sub rax, [start + timespec.tv_sec]
mov [deltatime + timespec.tv_sec], rax
; считаем наносекунды
mov rax, [finish + timespec.tv_nsec]
sub rax, [start + timespec.tv_nsec]
mov [deltatime + timespec.tv_nsec], rax
pop rax
%endmacro
%macro PRINT_DELTATIME 1
sub rsp, 8
mov rdi, str_template
mov rsi, %1
mov rdx, [deltatime + timespec.tv_sec]
mov rcx, [deltatime + timespec.tv_nsec]
call printf
add rsp, 8
%endmacro
main:
; В качестве базы возьму inc
; регистровая
;inc ecx
;mov rax, example
;xor rbx, rbx
;; косвенно-регистровая
;inc byte [rax]
;; "Индексно-базовая", хотя у меня почти все может быть базой
;inc byte [rax + rbx]
;; "Индексно-базовая" со смещением
;inc byte [rax + rbx + 122]
xor rax, rax ; поскольку приходим сюда из компилятора, лучше обнулить
TIME_1_000_000
nop
PRINT_DELTATIME nop_command
nop ; для дебага
TIME_1_000_000 inc rax
nop
PRINT_DELTATIME reg_command
nop
mov rax, example
TIME_1_000_000 inc byte [rax]
nop
PRINT_DELTATIME rel_reg
nop
mov rax, example
xor rbx, rbx
TIME_1_000_000 inc byte [rax + rbx]
nop
PRINT_DELTATIME ind_base
nop
mov rax, example
xor rbx, rbx
TIME_1_000_000 inc byte [rax + rbx + 122]
nop
PRINT_DELTATIME ind_base_disp
nop
xor rax, rax ; сообщаем gcc, что все закончилось успешно
ret