《汇编语言程序设计》例子之查找最大数

2024-06-18 05:28

本文主要是介绍《汇编语言程序设计》例子之查找最大数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        以下是第5章中讲到的 CMOV 的指令的例子,原来的源码是这样的:

# cmovtest.s - An example of the CMOV instructions
.section .data
output:.asciz "The largest value is %d\n"
values:.int 105, 235, 61, 315, 134, 221, 53, 145, 117, 5
.section .text
.globl _start
_start:nopmovl values, %ebxmovl $1, %edi
loop:movl values(, %edi, 4), %eaxcmp %ebx, %eaxcmova %eax, %ebxinc %edicmp $10, %edijne looppushl %ebxpushl $outputcall printfaddl $8, %esppushl $0call exit

当前使用环境为 Linux cnhz-cmpl42 4.15.0-197-generic #208-Ubuntu SMP Tue Nov 1 17:23:37 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux,这个程序是没法运行的。所以修改成如下:

# cmovtest.s - An example of the CMOV instructions
.section .data
output:.asciz "The largest value is %d\n"
values:.int 105, 235, 61, 315, 134, 21, 53, 145, 1117, 50
temp:.quad 0		#用于存放最大的那个数,因为这个参数是要加载到 rsi 寄存器的,如果用直接用原来的 ebx,则在 movl %ebx, %rsi 无法编译过,即使用 movq 也不行,#所以用一个临时变量存放
.section .text
.globl main
main:nopmovl $temp, %ecx		#将 temp的地址加载到 ecx 寄存器movl values, %ebxmovl $1, %edi
loop:movl values(, %edi, 4), %eaxcmp %ebx, %eaxcmova %eax, %ebxmovl %ebx, (%ecx)	#将最大值存放到 ecx 寄存器中地址所指的位置inc %edicmp $10, %edijne loopmovq $output, %rdimovq temp, %rsimovq $0, %raxcall printfret

Makefile:

CC = gcc
CFLAGS = -g -no-pie
SRCS = $(shell ls -t | grep "\.s$$" | head -1)a.out: $(SRCS)$(CC) -o $@ $(SRCS) $(CFLAGS).PHONY: clean
clean:rm -rf a.out

 

修改点:

1,修改入口点为 main,因为我直接用的 gcc 编译,Makefile 如上所示。

2,参数传送方式不一样了,movq $output, %rdi 和 movq temp, %rsi 传递第1、2 个参数,但在传递第2个参数时,如果直接用 movq %ecx, %rsi 会出现编译错误,这是两个不一样长度的寄存器,刚学我也不知道该如何正确使用,所以添加了一个临时变量来存放最大数,然后再从这个临时变量加载到 %rsi 寄存器中以达到目的。

以下还有另外一种写法,用的都是64位寄存器的名称,即全部使用以 r_ 开头的寄存器:

#cmov_test.s  -- An example of the CMOV instructions
.section .data
output:.string "The largest value is %d\n"
value: # 定义成 quad,即元素大小为 8 字节,所以下面的 value(,%rdi,8) 这里为 8.quad 15, 24, 61, 36, 134, 221, 63, 145, 117, 59.section .text
.global main
main:nopmovq value, %rbx	# 将 value 的第一个元素加载到 rbx 寄存器movq $1, %rdi		# 将立即数 1 加载到 rdi 寄存器
loop:movq value(, %rdi, 8), %rax		# 将偏移 value (%edi * 8) 个字节位置的值加载到 rax 寄存器,即第2、3、4、5、... 个元素cmp %rbx, %rax					# 比较两个寄存器里值的大小cmova %rax, %rbx				# 如果rax 里的值大于 rbx 里的值,则将 rax 里的值加载到 rbxinc %rdi						# 自增加 1cmp $10, %rdi					# 比较 rdi 里的值和立即数10,类似检查数组下标jne loop						# jump not equal -- 假如不等于则跳转到 loop 标签movq $output, %rdimovq %rbx, %rsimovq $0, %raxcall printfret

这篇关于《汇编语言程序设计》例子之查找最大数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1071419

相关文章

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

C语言程序设计(选择结构程序设计)

一、关系运算符和关系表达式 1.1关系运算符及其优先次序 ①<(小于) ②<=(小于或等于) ③>(大于) ④>=(大于或等于 ) ⑤==(等于) ⑥!=(不等于) 说明: 前4个优先级相同,后2个优先级相同,关系运算符的优先级低于算术运算符,关系运算符的优先级高于赋值运算符 1.2关系表达式 用关系运算符将两个表达式(可以是算术表达式或关系表达式,逻辑表达式,赋值表达式,字符

JavaFX环境的搭建和一个简单的例子

之前在网上搜了很多与javaFX相关的资料,都说要在Eclepse上要安装sdk插件什么的,反正就是乱七八糟的一大片,最后还是没搞成功,所以我在这里写下我搭建javaFX成功的环境给大家做一个参考吧。希望能帮助到你们! 1.首先要保证你的jdk版本能够支持JavaFX的开发,jdk-7u25版本以上的都能支持,最好安装jdk8吧,因为jdk8对支持JavaFX有新的特性了,比如:3D等;

javaScript日期相加减例子

当前时间加上2天 var d = new Date(“2015-7-31”); d.setDate(d.getDate()+2); var addTwo=d.getFullYear()+”年”+(d.getMonth()+1)+”月”+d.getDate()+”日”; “控制台输出===============”+”当前日期加2天:”+addTwo; 使用这种方法,月份也会给你计算.

Win8下如何快速查找和删除电脑中的病毒

Win8系统如何查找和删除病毒?检查你的电脑是否存在病毒的一种快速方法是使用 Windows Defender. 此恶意软件防护随 Windows 提供,可帮助识别和删除病毒、间谍软件和其他恶意软件。   注意:如果你使用的是 Windows RT,则 Windows Defender 会始终启用,并且不能关闭。   如果你使用的是 Windows 8,则可以根据自己的喜好运行由其他

nyoj 685 查找字符串

当初一开始没做出来。 后来,学习过一段时间之后,在返回来做这道题,忽然发现,map类容器可以做。 PS:需要注意的是:此题如果用c++的输入输出的话,会超时。 O(time):gets()<  scanf() < cin。   附上代码: #include<stdio.h>#include<map>#include<string>#include<string.h>usin

设计模式大全和详解,含Python代码例子

若有不理解,可以问一下这几个免费的AI网站 https://ai-to.cn/chathttp://m6z.cn/6arKdNhttp://m6z.cn/6b1quhhttp://m6z.cn/6wVAQGhttp://m6z.cn/63vlPw 下面是设计模式的简要介绍和 Python 代码示例,涵盖主要的创建型、结构型和行为型模式。 一、创建型模式 1. 单例模式 (Singleton

【C++二分查找】2439. 最小化数组中的最大值

本文涉及的基础知识点 C++二分查找 LeetCode2439. 最小化数组中的最大值 给你一个下标从 0 开始的数组 nums ,它含有 n 个非负整数。 每一步操作中,你需要: 选择一个满足 1 <= i < n 的整数 i ,且 nums[i] > 0 。 将 nums[i] 减 1 。 将 nums[i - 1] 加 1 。 你可以对数组执行 任意 次上述操作,请你返回可以得到的 n