Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 集合中三个数字的平均值_Assembly_Nasm_X86 64 - Fatal编程技术网

Assembly 集合中三个数字的平均值

Assembly 集合中三个数字的平均值,assembly,nasm,x86-64,Assembly,Nasm,X86 64,有人能帮我写一个程序,计算汇编中3个数字的平均值(NASM 64位)吗 我尝试的是: 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

有人能帮我写一个程序,计算汇编中3个数字的平均值(NASM 64位)吗

我尝试的是:

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:

;
; 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
;
; 使用标准C库的“Hello world”
;
; 建造:
; nasm-f elf64 avg3.asm
; gcc-m64-o平均值平均值
;
; 示例输出:
; 总和=12
; 平均值=4
;
extern printf;stdlibc函数
第节.案文;代码段
全球干线;标准GCC入口点
主要内容:
推动rbp;设置堆栈框架:必须对齐
; 加上3+4+5
莫夫·拉克斯,3
加上斧头,4
加上斧头,5
; 保存并打印总和
推拉
mov-rdi,fmt1;printf格式字符串
mov-rsi,rax;第一参数
mov-rdx,0;没有第二个参数
mov-rax,0;没有xmm寄存器
调用printf
; 计算并打印平均值
mov-dx,0;净股息,高

波普雷克斯;股息,低Q:什么是操作系统?问:您对该操作系统的“系统调用”是什么?问:你的问题到底是什么/你遇到了什么问题?我很困惑,你认为在汇编中找不到平均值是什么样的?好像你把一堆东西移到了rax中。
mov-rax,num1
用NASM语法将
rax
设置到
num1
的地址
mov rax,[num1]
将是一个64位的加载,设置
rax=0x???0a0003050403
(x86是小尾端,而
db
只有1字节宽)。除此之外,您还未设置RDX。对于
div
,需要将其归零。在静态链接的二进制文件中,Linux将在
\u start
之前将其归零,但在其他任何地方,此代码都可能因#DE divide异常中的SIGFPE而崩溃。无论如何,您希望
movzx eax、byte[num1]
等进入不同的寄存器,以便为
add
设置,或者希望
add al[num2]
以此类推以获取后面的数字。@paulsm4操作系统是Linux 64位(mint)。在第一个示例中,
int 0x80
只在64位代码中工作,因为您在静态缓冲区上使用了
sys\u write
,并且您设置了位置相关(非饼图)可执行文件,以便静态代码/数据位于虚拟地址空间的低位32位。这一点说得很好,谢谢。我只是想创造一个“最简单的例子”。如果您建议“更好的东西”,我很乐意更新示例。在第二个示例中,您调用
printf
,堆栈未对齐16(函数输入后2x
push
),违反了ABI。它恰好在当前glibc(AL=0)上工作,但允许SEGFULT。不要使用RBP作为帧指针,而是使用它来保存总和。e、 g.
mov ebp,3
/
添加ebp,4+5
/
mov esi,ebp
/。。。printf/
mov-eax,ebp
/
xor-edx,edx
/
div
/
mov-esi,eax
。(或者只使用3个参数进行一次printf调用,因此您不需要保存/恢复其中的总和。)这里使用16位寄存器也没有任何好处。要修复第一个示例:OP已经使用64位
sys\u write
sys\u exit
,我的答案是64位Hello World(包括一些额外的东西来为这个答案做一个例子,但它可以简化。)问:
push-rax
的哪一部分没有让堆栈以16的倍数对齐?我不是在“争论”——我只是好奇在这个例子中什么是“有效推送”。