Среднее из трех чисел в сборке - PullRequest
0 голосов
/ 03 октября 2018

Может кто-нибудь помочь мне написать программу, которая вычисляет среднее из 3-х чисел в сборке (64-битный NASM)?

Что я пробовал:

section .data
    num1 db 3
    num2 db 4
    num3 db 5
    divisor db 3
    digit db 0, 10

section .text
    global _start
    _start:
        mov rax, num1
        mov rax, num2
        div rax, num3
        mov rbx, divisor
        div rbx
        mov rax, 60
        mov rdi, 0
        syscall
    _printRAX:
        add rax, 48
        mov [digit], al
        mov rax, 1
        mov rdi, 1
        mov rsi, digit
        mov rdx, 2
        syscall
        ret

1 Ответ

0 голосов
/ 04 октября 2018

ОК, вот два примера, которые могут помочь:

ПРИМЕР 1:

;
; Standalone NASM "Hello world"
;
; BUILD:
; nasm -f elf64 hello.asm
; ld -s -o hello hello.o
;
; EXAMPLE OUTPUT:
; Hello, world!
;
section .text                   ;code section (shareable between processes)
    global  _start              ;loader entry point

_start:
    mov     edx,len             ;arg3: msg len
    mov     ecx,msg             ;arg2: *msg
    mov     ebx,1               ;arg1: 1 (stdout)
    mov     eax,4               ;syscall@4 (sys_write)
    int     0x80

    mov     ebx,0               ;arg1: exit code (0)
    mov     eax,1               ;sycall@1 (sys_exit)
    int     0x80

section .data                   ;data section (per process)
msg db      "Hello, world!",0xa ;our dear string
len equ     $ - msg             ;length of our dear string

ПРИМЕР 2:

;
; "Hello world" using standard C library
;
; BUILD:
; nasm -f elf64 avg3.asm
; gcc -m64 -o avg avg.o
;
; EXAMPLE OUTPUT:
; sum=12
; avg=4
;
extern  printf                  ;stdlib C function

section .text                   ;code section
    global  main                ;standard GCC entry point

main:
    push rbp                    ;set up stack frame: must be aligned

    ; Add 3+4+5
    mov     rax,3
    add     ax,4
    add     ax,5

    ; Save and print sum
    push    rax
    mov     rdi,fmt1            ;printf format string
    mov     rsi,rax             ;1st parameter
    mov     rdx,0               ;No 2nd parameter
    mov     rax,0               ;No xmm registers
    call    printf

    ; Compute and print average
    mov     dx,0                ;Clear dividend, high
    pop     rax                 ;dividend, low <= sum
    mov     cx,3                ;divisor
    div     cx                  ;ax= high, dx= low

    ; Print average
    mov     rdi,fmt2            ;printf format string
    mov     rsi,rax             ;1st parameter
    mov     rdx,0               ;No 2nd parameter
    mov     rax,0               ;No xmm registers
    call    printf

    ; Exit program
    pop rbp
    mov rax,0
    ret

section .data                   ;data section
fmt1:
    db      "sum=%d",0xa,0
fmt2:
    db      "avg=%d",0xa,0

ПРИМЕЧАНИЯ:

  • Лично я предпочитаю "Gnu Assembler" ( gas ).Это позволяет легко переключаться между различными архитектурами, а также между C и встроенным ассемблером, без «когнитивного диссонанса» при работе с синтаксисом Intel;)

  • Я настоятельно призываю васиспользовать стандартную библиотеку C имеет как можно больше.На практике это означает связывание вашего исполняемого файла с использованием gcc вместо ld .

    Ваша программа «вычисления по среднему» является отличным примером того, почему: гораздо проще позволитьprintf formatter выяснит правильный вывод, а не преобразовывает ваши двоичные значения в ASCII-цифры, а затем выяснит, как отформатировать их в строку вручную.

'Надеюсь, это поможет!

...