123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 | section .text ; program test
global _start ; _start is default; export for linker
extern printf
_start: ; _start (default start point) sub/func
mov r14, 0x08 ; start value: +8
mov cl, 1 ; shift 1
call left_logic ; shift left, logical
mov cl, 2 ; shift 2
call left_logic ; shift left, logical
mov cl, 4 ; shift 4
call left_logic ; shift left, logical
mov r14, -0x08 ; start value: -8
mov cl, 1 ; shift 1
call left_arith ; shift left, arithmetic
mov cl, 2 ; shift 2
call left_arith ; shift left, arithmetic
mov cl, 4 ; shift 4
call left_arith ; shift left, arithmetic
mov r14, 0x08 ; start value: +8
mov cl, 1 ; shift 1
call right_logic ; shift right, logical
mov cl, 2 ; shift 2
call right_logic ; shift right, logical
mov cl, 4 ; shift 4
call right_logic ; shift right, logical
mov r14, -0x08 ; start value: -8
mov cl, 1 ; shift 1
call right_arith ; shift right, arithmetic
mov cl, 2 ; shift 2
call right_arith ; shift right, arithmetic
mov cl, 4 ; shift 4
call right_arith ; shift right, arithmetic
mov cl, 8 ; shift 8
call right_arith ; shift right, arithmetic
; next section is exit routine
mov ebx, 0 ; exit code: 0 (success)
mov eax, 1 ; system call: sys_exit
int 0x80 ; call kernel
left_logic: ; logical shift left
mov r10, r14 ; store initial value
shl r10, cl ; shift
xor rdx, rdx ; clear rdx
mov dl, cl ; store shift amount to print later
mov rcx, r10 ; store initial value to print
mov r15, leftsl ; string for logical shifting left
call print_int ; print
mov r15, leftl ; asm notation for logical shifting left
call print_int ; print
ret
left_arith: ; arithmetic shift left
mov r10, r14 ; store initial value
sal r10, cl ; shift
xor rdx, rdx ; clear rdx
mov dl, cl ; store shift amount to print later
mov rcx, r10 ; store initial value to print
mov r15, leftsa ; string for arithmetic shifting left
call print_int ; print
mov r15, lefta ; asm notation for arithmetic shifting left
call print_int ; print
ret
right_logic: ; logical shift right
mov r10, r14 ; store initial value
shr r10, cl ; shift
xor rdx, rdx ; clear rdx
mov dl, cl ; store shift amount to print later
mov rcx, r10 ; store initial value to print
mov r15, rightsl ; string for logical shifting right
call print_int ; print
mov r15, rightl ; asm notation for logical shifting right
call print_int ; print
ret
right_arith: ; arithmetic shift right
mov r10, r14 ; store initial value
sar r10, cl ; shift
xor rdx, rdx ; clear rdx
mov dl, cl ; store shift amount to print later
mov rcx, r10 ; store initial value to print
mov r15, rightsa ; string for arithmetic shifting right
call print_int ; print
mov r15, righta ; asm notation for arithmetic shifting right
call print_int ; print
ret
print_int:
push rax ; store all the registers (overkill? yes)
push rbx
push rcx
push rdx
push rsi
push rdi
push rbp
push rsp
push r8
push r9
push r10
push r11
push r12
push r13
mov rsi, r14 ; value stored in r14
mov rdi, r15 ; string stored in r15
mov eax, 0 ; no non-int args
call printf ; call printf
pop r13 ; pop all the registers
pop r12
pop r11
pop r10
pop r9
pop r8
pop rsp
pop rbp
pop rdi
pop rsi
pop rdx
pop rcx
pop rbx
pop rax
ret
section .data ; program data
leftl db "Logical shifted %d left %d, result: %d", 10, 0
leftsl db "shl %2d, %d == %4d", 9, 0
rightl db "Logical shifted %d right %d, result: %d", 10, 0
rightsl db "shr %2d, %d == %4d", 9, 0
lefta db "Arithmetic shifted %d left %d, result: %d", 10, 0
leftsa db "sal %2d, %d == %4d", 9, 0
righta db "Arithmetic shifted %d right %d, result: %d", 10, 0
rightsa db "sar %2d, %d == %4d", 9, 0
|