当前位置: 首页 > news >正文

网站建设订制版合同模板如何新建站点

网站建设订制版合同模板,如何新建站点,企业网怎么拉,淘宝seo搜索排名优化说明:本节的程序使用的是x86_64指令集的。 汇编语言是可以编译成机器指令的#xff0c;机器指令是可以直接在CPU上面执行的。我们编写的汇编程序既可以直接在操作系统的帮助下执行#xff0c;也可以绕过操作系统#xff0c;直接在硬件上执行。 如果你打算编写的汇编程序在…说明:本节的程序使用的是x86_64指令集的。 汇编语言是可以编译成机器指令的机器指令是可以直接在CPU上面执行的。我们编写的汇编程序既可以直接在操作系统的帮助下执行也可以绕过操作系统直接在硬件上执行。 如果你打算编写的汇编程序在操作系统帮助下执行那么你的汇编可以调用很多操作系统暴露的系统调用或者别的语言的函数库比如C语言的标准库中的函数。但是如果你打算编写绕过操作系统执行的汇编会比较累比如往显示器上显示一串字符串这件事情如果你打算让操作系统帮你执行你可以在汇编程序中直接调用系统调用这一节我们打算这么做来控制硬件操作系统能帮助我们控制硬件如果你打算自己去控制硬件就比较麻烦点下一节我们打算这么做。 Hello World汇编文件编写 hello.asm文件的内容等一会再详细剖析代码 ;hello.asm 交给nasm汇编器汇编的程序通过英文分号开头表示注释 section .datamsg db Hello, wolrd,0,0xA ;db表示define byte即字节类型逗号后边的0表示字符串结尾;字符串中的每个字符占用一个字节,0xA是十六进制数对应的换行符的ASCII码;这样后边输出字符串的时候就可以还行了 section .bss section .textglobal main main:mov rax,1 ;为了后续使用syscall先将系统调用号1含义是write存到寄存器rax中mov rdi,1 ;rdi寄存器通常表示目的地1表示标准输出mov rsi,msg ;rsi寄存器通常表示来源地需要显示的是字符串存放在rsi中mov rdx,14 ;字符串的长度和末尾的0及换行符的长度。注意汇编中的数字如果不加0x前缀或者h后缀表示的是十进制syscall ;发起x86_64的系统调用显示字符串mov rax,60 ;程序的返回结果放在rax寄存器中60表示退出如果为负数表示发生了错误mov rdi,0 ;0表示成功退出码syscall ;退出hello.asm同一个目录下的makefile文件内容 #hello.asm的makefile makefile的注释用#开头 hello: hello.o # no-pie选项是为了关闭pie从而生成可调试的可执行文件 # pie是position independent executable的意思表示与地址无关的 # 如果编译器在生成可执行程序的过程中使用了pie那么当可执行程序被加载到内存中时其加载地址存在不可预知性gcc -o hello hello.o -no-pie hello.o: hello.asm # nasm -f 后边表示的是输出的格式 # elf64表示的是64位可执行和可链接的格式nasm -f elf64 hello.asm编译、执行 pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ pwd /home/pilaf/assembly_x64/hello_asm pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ ls hello.asm makefile pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ make nasm -f elf64 hello.asm gcc -o hello hello.o -no-pie pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ ls hello hello.asm hello.o makefile pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ ./hello Hello, wolrd pilafpilaf-thinkpad:~/assembly_x64/hello_asm$ make命令后生成了一个可执行的hello文件然后执行它在shell中输出了Hello, world。 反编译可执行文件 下面我们通过gdb看一下hello可执行程序反汇编的结果 dissassemble/r main可以显示出main函数global main定义的十六进制指令及其汇编指令关系最左边的蓝色的一列是二进制可执行程序的内存地址逻辑地址。可以看到syscall指令的机器码是0f05。 上边很有意思的是这几行 0x0000000000401110 0: b8 01 00 00 00 mov eax,0x10x0000000000401115 5: bf 01 00 00 00 mov edi,0x10x000000000040111a 10: 48 be 28 40 40 00 00 00 00 00 movabs rsi,0x4040280x0000000000401124 20: ba 0e 00 00 00 mov edx,0xe0x0000000000401129 25: 0f 05 syscall 0x000000000040112b 27: b8 3c 00 00 00 mov eax,0x3c0x0000000000401130 32: bf 00 00 00 00 mov edi,0x0内存地址后边跟着的尖括号中的数字表示相对第一个指令的内存地址的偏移字节数。 第二条指令mov edi,0x1相对于第一条指令mov eax,0x1偏移了5个字节正好就是b8 01 00 00 00这5个字节所占的内存长度。而mov edi,0x1也占用了5个字节的内存所以它后便的内存中的指令movabs rsi,0x404028相对于它又增加了5个字节10-55。 还有我们发现有mov eax的地方机器码都是b8开头有mov edi的地方机器码都是bf开头后便跟着4个字节就是mov指令有操作数。这也就是说了mov eaxmov edi在指令中一共才占用1个字节这1个字节就表示了mov和寄存器两个信息了。 我们还可以发现b8、bf后边跟着的4个字节32位整数的十六进制表示和mov指令右操作数好像不一样啊其实这是因为Intel CPU采用的是小端字节序对应的还有大端字节序。所谓的大端还是小端指的是将一个多字节的数存放到内存的时候这个数字的权重大的字节比如十进制的102这个数字的1的权重比2大放在内存低地址还是权重小的字节放在内存低地址。如果权重低的字节放在内存低地址就是小端字节序如果权重大的字节放在内存低地址就是大端字节序。 我们的0x01是0x00000001这个四字节数的简写但是却把01这个字节放在内存低地址所以它是小端字节序。 等等不知道你有没有发现一个问题我们hello.asm中用的不是rax么怎么反编译完了变成了eax了好多r开头的寄存器怎么都变成e开头的了这是因为r开头的寄存器是64位的e开头的是32位的汇编器发现mov右操作数没有必要用64位寄存器存储就优化了。不知你是否还记得8086的几个通用寄存器ax、bx、cx、dx它们又可以拆分为两个8位寄存器如ah、alh表示highl表示low80386开始有eax、ebx、ecx、edxe表示extend扩展的意思它们都是32位的寄存器了到了64位有了rax、rbx、rcx、rdx这些寄存器。类似的还有ip、eip、rip表示存放下一个指令内存地址的寄存器。 系统调用方式之syscall 好了让我们再来看看syscall这个汇编指令。 书上说进行系统调用的可以通过下面三种方式 INT中断Interrupt旧的方式不太推荐用了syscall指令syscall是汇编指令我们hello.asm中用到了程序库API如C语言的标准库中的printf就对write系统调用进行了封装 作为菜鸟的我看到《x64汇编语言从新手到AVX专家》中给出的这段汇编有很多地方不明白的比如mov rax,1和mov rdi,1中的1有什么联系为什么要往rax中mov不往别的寄存器mov 带着这些疑问我man了一下syscallLinux shell中执行了man syscall 内容很长我只截了一部分。从中我们可以看到C头文件中也定义了一个syscall的函数名字和汇编的syscall指令相同它是一个小的库函数它用于调用一些系统调用这些系统调用系统调用是操作系统对硬件操作的封装对硬件操作少不了汇编指令Linux操作系统的系统调用的实现都是C语言中嵌套着汇编的汇编接口有特定的号码和参数。syscall函数可以调用其它的系统调用只需要按照调用约定将系统调用号和参数传递给它即可。 也就是说汇编提供了一个syscall指令用于调用操作系统的系统调用只需要将操作系统的系统调用号和参数准备好就可以了。 我们可以通过汇编直接调用syscall指令也可以用C语言提供的syscall函数这个函数内部实现肯定是包了汇编指令syscall的。 并且系统调用号的数字和符号表示关系在sys/syscall.h中有定义。 syscall汇编指令的用法 我继续阅读man syscall给出的信息发现下面这些有用的信息。 表一 文档直接给出了x86-64的syscall指令的使用方法也就是说调用syscall之前需要将系统调用号System call #英文中经常用井号表示Number的缩写放到rax寄存器返回值1放到rax中返回值2放到rdx中。 还有下面的入参信息。 表二 说明了x86-64的系统调用的参数1放在rdi寄存器中参数2放在rsi寄存器中参数3放在rdx寄存器中参数4放在r10寄存器中参数5放在r8寄存器中参数6放在r9寄存器中。 回到我们的hello.asm我们用了汇编的syscall指令调用了操作系统的系统调用按照上面截图中说的x86-64使用syscall汇编指令的时候会将操作系统的系统调用号放到rax寄存器中我们的程序写的是mov rax,1也就是说系统调用号是1我们刚才看到说系统调用号和它的符号表示在sys/syscall.h头文件中的我们在CLionJetbrains全家桶中的C语言集成开发环境IDE中随便打开一个c文件引入头文件 一路追踪下来终于发现操作系统调用号为1的系统调用名称是write废话不多说直接执行man 2 write看看 可以看到Linux操作系统的write系统调用的参数有三个第一个是文件描述符Linux中一切皆文件0表示标准输入1表示的标准输出文件描述符2表示错误输出第二个参数是一个指针即输入内容起始内存地址第三个参数表示输入的字节数。 上面表二中说了Linux操作系统的系统调用的入参第一个放到rdi寄存器第二个放到rsi寄存器第三个放到rdx寄存器等等。结合man 2 write得到的知识传递给write系统调用的三个参数分别是1msg的地址14Hello, world字符及其结尾0加上换行一共14字节。 也就是说我们的hello.asm干了这么件事情通过汇编的syscall指令调用了Linux系统调用write让write往标准输出上面输出14个字节内容是Hello, world然后换行。 总结 作为菜鸟的我在运行书中的一段hello world程序的时候书中很多地方没有写明为什么这样做笔者通过一点点摸索终于搞清楚其底层的运行逻辑顿感欢喜以此记录希望能帮到和我一样菜的菜鸟。也希望大家不要浮躁沉下心来夯实基础做一个有工匠精神的码农也许某一天平时积累的点滴就派上了大用场。加油 参考资料 1.《x64汇编语言从新手到AVX专家》 2.《汇编程序设计与计算机体系结构 软件工程师教程》P211
http://www.w-s-a.com/news/265687/

相关文章:

  • 建设一个旅游网站毕业设计企业网站要更新文章吗
  • 做网站需要简介中山网站设计公司
  • 网站怎么做导航栏微信公众号官网登录
  • 1_ 掌握网站开发的基本流程 要求:熟悉网站开发与设计的基本流程.电子商城网站开发
  • 百度网站怎么建设河北省工程造价信息网官网
  • 阿里云网站模板网页设计的合适尺寸是多少
  • 做小程序和做网站哪个好让别人做网站推广需要多少钱
  • 做外贸的几个网站查询网域名解析
  • 酒泉如何做百度的网站seo研究中心好客站
  • 网站设计建设平台户县做网站
  • 一元云购网站开发wordpress博客空间
  • 深圳高端网站建设公司排名如何搭建局域网服务器
  • 照片管理网站模板高端网站开发哪家好
  • 黄冈网站制作wordpress为什么不能显示域名
  • 做网站设计怎么进企业电子商务网站建设与管理教材
  • 设计广告公司网站建设网站开发技术选择
  • 个人网站教程个人网站有必要备案吗
  • 网站建设推广好做吗黄浦企业网站制作
  • 怎样做28网站代理中山网站建设方案外包
  • vs2010做网站前台搭建小网站
  • 做视频必须知道的一些网站wordpress 标签鼠标滑过_弹出的title 代码美化
  • 怎么做室内设计公司网站电商运营培训视频课程
  • 昆明网站策划天津市建筑信息平台
  • 三亚放心游app官方网站wordpress 个人主题
  • 做简单的网站备案平台新增网站
  • 中国建设网站银行网络营销推广方案整合
  • 网站域名列表dede网站白屏
  • 站长工具一区品牌建设卓有成效
  • 电子商务网站建设案例wordpress批量编辑
  • 想代理个网站建设平台100个最佳市场营销案例