Assembly 集合中三个数字的平均值
有人能帮我写一个程序,计算汇编中3个数字的平均值(NASM 64位)吗 我尝试的是: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
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(函数输入后2xpush
),违反了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的倍数对齐?我不是在“争论”——我只是好奇在这个例子中什么是“有效推送”。