Guest User

Untitled

a guest
Nov 10th, 2026
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 6.48 KB | Source Code | 0 0
  1.  
  2. ; kalkulator.asm
  3. ; x86-64 Linux / NASM / Box64
  4. ; Decimal fixed point: 8 decimal places
  5. ; No libc
  6.  
  7. section .data
  8.     prompt  db "> "
  9.     plen    equ $-prompt
  10.     newline db 10
  11.     scale   dq 100000000
  12.     ten     dq 10
  13.  
  14. section .bss
  15.     buf     resb 128
  16.     outbuf  resb 128
  17.     intbuf  resb 32
  18.     acc     resq 1
  19.     operand resq 1
  20.     op      resb 1
  21.  
  22. section .text
  23.     global _start
  24.  
  25. _start:
  26.     mov qword [acc], 0
  27.     mov byte [op], 0
  28.  
  29. ; ================================================
  30. ; Main loop
  31. ; ================================================
  32.  
  33. main_loop:
  34.     ; Prompt
  35.     mov eax, 1
  36.     mov edi, 1
  37.     mov rsi, prompt
  38.     mov edx, plen
  39.     syscall
  40.  
  41.     ; Read line
  42.     xor eax, eax
  43.     xor edi, edi
  44.     mov rsi, buf
  45.     mov edx, 128
  46.     syscall
  47.  
  48.     test rax, rax
  49.     jle exit
  50.  
  51.     mov r14, rax
  52.  
  53.     ; Skip leading spaces
  54.     xor r8, r8
  55.  
  56. skip_spaces:
  57.     cmp r8, r14
  58.     jge main_loop
  59.  
  60.     mov al, [buf+r8]
  61.     cmp al, ' '
  62.     jne first_char
  63.     inc r8
  64.     jmp skip_spaces
  65.  
  66. first_char:
  67.     cmp al, 'q'
  68.     je exit
  69.  
  70.     ; Operator?
  71.     cmp al, '+'
  72.     je operator_found
  73.     cmp al, '-'
  74.     je operator_found
  75.     cmp al, '*'
  76.     je operator_found
  77.     cmp al, '/'
  78.     je operator_found
  79.  
  80.     ; Otherwise parse number
  81.     lea rsi, [buf+r8]
  82.     mov rdx, r14
  83.     sub rdx, r8
  84.     call parse_number
  85.  
  86.     mov [operand], rax
  87.  
  88.     cmp byte [op], 0
  89.     jne calculate
  90.  
  91.     ; No pending operation: set accumulator
  92.     mov [acc], rax
  93.     jmp show_result
  94.  
  95. operator_found:
  96.     mov [op], al
  97.     inc r8
  98.  
  99.     ; Skip spaces after operator
  100. operator_spaces:
  101.     cmp r8, r14
  102.     jge main_loop
  103.  
  104.     mov al, [buf+r8]
  105.     cmp al, ' '
  106.     jne inline_number
  107.     cmp al, 10
  108.     je main_loop
  109.     inc r8
  110.     jmp operator_spaces
  111.  
  112. inline_number:
  113.     cmp al, 10
  114.     je main_loop
  115.     cmp al, 13
  116.     je main_loop
  117.  
  118.     ; Operator and number on same line
  119.     lea rsi, [buf+r8]
  120.     mov rdx, r14
  121.     sub rdx, r8
  122.     call parse_number
  123.  
  124.     mov [operand], rax
  125.     jmp calculate
  126.  
  127. ; ================================================
  128. ; Parse decimal fixed-point number
  129. ; Input: RSI = pointer, RDX = length
  130. ; Output: RAX = signed fixed-point value
  131. ; ================================================
  132.  
  133. parse_number:
  134.     mov r9, rdx
  135.  
  136.     xor rbx, rbx        ; integer part
  137.     xor r12, r12        ; fractional part
  138.     xor r13, r13        ; fractional digits
  139.     xor r8, r8          ; decimal point flag
  140.     xor r15, r15        ; sign
  141.     xor rcx, rcx        ; index
  142.  
  143.     ; Optional sign
  144.     mov al, [rsi]
  145.     cmp al, '-'
  146.     jne check_plus
  147.  
  148.     mov r15, 1
  149.     inc rcx
  150.     jmp parse_loop
  151.  
  152. check_plus:
  153.     cmp al, '+'
  154.     jne parse_loop
  155.     inc rcx
  156.  
  157. parse_loop:
  158.     cmp rcx, r9
  159.     jge parse_done
  160.  
  161.     movzx rax, byte [rsi+rcx]
  162.     inc rcx
  163.  
  164.     cmp al, 10
  165.     je parse_done
  166.     cmp al, 13
  167.     je parse_done
  168.     cmp al, ' '
  169.     je parse_done
  170.  
  171.     cmp al, '.'
  172.     je decimal_point
  173.  
  174.     sub al, '0'
  175.     cmp al, 9
  176.     ja parse_done
  177.  
  178.     movzx rdx, al
  179.  
  180.     test r8, r8
  181.     jnz fractional_digit
  182.  
  183.     imul rbx, rbx, 10
  184.     add rbx, rdx
  185.     jmp parse_loop
  186.  
  187. fractional_digit:
  188.     cmp r13, 8
  189.     jge parse_loop
  190.  
  191.     imul r12, r12, 10
  192.     add r12, rdx
  193.     inc r13
  194.     jmp parse_loop
  195.  
  196. decimal_point:
  197.     mov r8, 1
  198.     jmp parse_loop
  199.  
  200. parse_done:
  201.     ; Pad fraction to 8 digits
  202.     cmp r13, 8
  203.     jge make_number
  204.  
  205.     imul r12, r12, 10
  206.     inc r13
  207.     jmp parse_done
  208.  
  209. make_number:
  210.     mov rax, rbx
  211.     imul rax, 100000000
  212.     add rax, r12
  213.  
  214.     test r15, r15
  215.     jz parse_return
  216.  
  217.     neg rax
  218.  
  219. parse_return:
  220.     ret
  221.  
  222. ; ================================================
  223. ; Arithmetic
  224. ; ================================================
  225.  
  226. calculate:
  227.     mov rax, [acc]
  228.     mov rbx, [operand]
  229.  
  230.     mov cl, [op]
  231.  
  232.     cmp cl, '+'
  233.     je addition
  234.  
  235.     cmp cl, '-'
  236.     je subtraction
  237.  
  238.     cmp cl, '*'
  239.     je multiplication
  240.  
  241.     cmp cl, '/'
  242.     je division
  243.  
  244.     jmp clear_operation
  245.  
  246. addition:
  247.     add rax, rbx
  248.     jmp save_result
  249.  
  250. subtraction:
  251.     sub rax, rbx
  252.     jmp save_result
  253.  
  254. multiplication:
  255.     ; (acc * operand) / scale
  256.     imul rbx
  257.     idiv qword [scale]
  258.     jmp save_result
  259.  
  260. division:
  261.     ; (acc * scale) / operand
  262.     test rbx, rbx
  263.     jz clear_operation
  264.  
  265.     imul qword [scale]
  266.     idiv rbx
  267.     jmp save_result
  268.  
  269. save_result:
  270.     mov [acc], rax
  271.  
  272. clear_operation:
  273.     mov byte [op], 0
  274.  
  275. show_result:
  276.     call print_acc
  277.     jmp main_loop
  278.  
  279. ; ================================================
  280. ; Print accumulator
  281. ; ================================================
  282.  
  283. print_acc:
  284.     mov rax, [acc]
  285.  
  286.     xor r15, r15
  287.     test rax, rax
  288.     jns print_positive
  289.  
  290.     neg rax
  291.     mov r15, 1
  292.  
  293. print_positive:
  294.     ; Separate integer and fractional parts
  295.     xor rdx, rdx
  296.     div qword [scale]
  297.  
  298.     mov r12, rax
  299.     mov r13, rdx
  300.  
  301.     lea rdi, [outbuf]
  302.  
  303.     ; Sign
  304.     test r15, r15
  305.     jz convert_integer
  306.  
  307.     mov byte [rdi], '-'
  308.     inc rdi
  309.  
  310. convert_integer:
  311.     ; Convert integer part backwards
  312.     lea r8, [intbuf+31]
  313.     mov rax, r12
  314.  
  315.     test rax, rax
  316.     jnz integer_loop
  317.  
  318.     dec r8
  319.     mov byte [r8], '0'
  320.     jmp copy_integer
  321.  
  322. integer_loop:
  323.     xor rdx, rdx
  324.     div qword [ten]
  325.  
  326.     add dl, '0'
  327.     dec r8
  328.     mov [r8], dl
  329.  
  330.     test rax, rax
  331.     jnz integer_loop
  332.  
  333. copy_integer:
  334.     mov rsi, r8
  335.     lea r9, [intbuf+32]
  336.  
  337. copy_loop:
  338.     cmp rsi, r9
  339.     jge integer_done
  340.  
  341.     mov al, [rsi]
  342.     mov [rdi], al
  343.  
  344.     inc rsi
  345.     inc rdi
  346.     jmp copy_loop
  347.  
  348. integer_done:
  349.     ; Fraction zero?
  350.     test r13, r13
  351.     jz output_result
  352.  
  353.     mov byte [rdi], '.'
  354.     inc rdi
  355.  
  356.     ; Generate exactly 8 decimal digits
  357.     mov r10, r13
  358.     mov r11, 10000000
  359.  
  360. fraction_loop:
  361.     mov rax, r10
  362.     xor rdx, rdx
  363.     div r11
  364.  
  365.     add al, '0'
  366.     mov [rdi], al
  367.     inc rdi
  368.  
  369.     mov r10, rdx
  370.  
  371.     mov rax, r11
  372.     xor rdx, rdx
  373.     div qword [ten]
  374.     mov r11, rax
  375.  
  376.     test r11, r11
  377.     jnz fraction_loop
  378.  
  379.     ; Remove trailing zeros
  380. trim_fraction:
  381.     cmp byte [rdi-1], '0'
  382.     jne trim_done
  383.  
  384.     dec rdi
  385.     jmp trim_fraction
  386.  
  387. trim_done:
  388.     cmp byte [rdi-1], '.'
  389.     jne output_result
  390.  
  391.     dec rdi
  392.  
  393. output_result:
  394.     mov byte [rdi], 10
  395.     inc rdi
  396.  
  397.     mov rsi, outbuf
  398.     mov rdx, rdi
  399.     sub rdx, rsi
  400.  
  401.     mov eax, 1
  402.     mov edi, 1
  403.     syscall
  404.  
  405.     ret
  406.  
  407. ; ================================================
  408. ; Exit
  409. ; ================================================
  410.  
  411. exit:
  412.     mov eax, 60
  413.     xor edi, edi
  414.     syscall
  415.  
Advertisement
Add Comment
Please, Sign In to add comment