首页 > 编程语言 >汇编语言学习_4_函数

汇编语言学习_4_函数

时间:2023-02-28 16:33:25浏览次数:47  
标签:函数 汇编语言 mov helloworld 学习 eax len 使用

第四节

函数

翻译自:https://asmtutor.com/

介绍函数(子程序)

函数 / 子程序 (functions/subroutines)是可重用的代码片段,程序可以调用它们来执行各种可重复的任务。函数是使用 标签 声明的,就像我们之前使用的那样(例如 _start:),但是我们不使用 JMP 指令来访问它们,而是使用新的指令 CALL。在运行函数后,也不会使用 JMP 指令返回到原程序。要从函数返回到原程序,使用指令 RET

为什么不直接用JMP跳转

编写函数的好处就是可以重用它。如果我们想从代码中的任何地方使用函数,可能必须编写一些逻辑代码来确定我们从代码中跳到了哪里,并且应该跳回到哪里。这会使我们的代码中充斥着不需要的标签。但是,如果我们使用 CALLRET,程序会使用栈(stack)为我们处理这个问题。

介绍栈

栈(stack)是一种特殊类型的内存。它与我们以前使用过的内存类型相同,但在程序使用它的方式上很特殊。栈称为后进先出内存(Last In First Out,LIFO)。可以把栈想象成厨房里的一栈盘子,放在栈上的最后一个盘子也是你下次使用盘子时将从栈上取下的第一个盘子。

汇编程序中栈的不是存储盘子,而是存储值。你可以在堆栈上存储很多东西,比如变量、地址或其他程序。当调用函数时,我们需要使用栈来临时存储函数返回后要恢复的值。

函数需要使用的任何寄存器都应该将其当前值放入栈中,以便使用 PUSH 指令安全保存。然后,在函数完成其逻辑之后,这些寄存器可以使用 POP 指令恢复其原始值。这样便可保证在调用函数前后,寄存器中的任何值都没有变化。如果我们在函数中处理好这一点,我们就可以随意调用函数,而不用担心它们对寄存器做了什么更改。

CALLRET 指令也使用栈。当 CALL 一个函数时,调用地址被push到栈上。函数结束时,RET 将这个地址从栈中pop,以跳回到调用位置。

; Hello World Program (Subroutines)
; 编译: nasm -f elf helloworld-len.asm
; 链接 (64 bit 系统需要 elf_i386 选项): ld -m elf_i386 helloworld-len.o -o helloworld-len
; 运行: ./helloworld-len
 
SECTION .data
msg     db      'Hello, brave new world!', 0Ah
 
SECTION .text
global  _start
 
_start:
 
    mov     eax, msg        ; 将信息字符串地址移动到 EAX
    call    strlen          ; 调用函数去计算字符串长度
 
    mov     edx, eax        ; 函数将返回值放在 EAX
    mov     ecx, msg        ; 与之前的代码相同
    mov     ebx, 1
    mov     eax, 4
    int     80h
 
    mov     ebx, 0
    mov     eax, 1
    int     80h
 
strlen:                     ; 这是我们第一个函数的声明
    push    ebx             ; 将EBX中的值保存于栈上,因为strlen会使用该它
    mov     ebx, eax        ; 将EAX中msg的地址移EBX(现在二者指向内存中同一处)
 
nextchar:                   ; 与第三节相同
    cmp     byte [eax], 0
    jz      finished
    inc     eax
    jmp     nextchar
 
finished:
    sub     eax, ebx
    pop     ebx             ; 将栈上元素放回 EBX
    ret                     ; 返回函数
~$ nasm -f elf helloworld-len.asm
~$ ld -m elf_i386 helloworld-len.o -o helloworld-len
~$ ./helloworld-len
Hello, brave new world!

标签:函数,汇编语言,mov,helloworld,学习,eax,len,使用
From: https://www.cnblogs.com/chai-yuan/p/17164804.html

相关文章

  • 记一次 python+allure 的学习
    1、allure下载地址:https://github.com/allure-framework/allure2/releases 下载完成后,配置window的环境变量,到bin目录 配置完成后,cmd命令窗口输入以下命令,检......
  • MogDB 学习笔记之 -- 索引失效
    [[toc]]#概念描述哪些操作会导致分区表的全局索引失效(比如movepartition,droppartition,truncatepartition,splitpartition,mergepartitions)#测试验证1、环境准......
  • JAVA基础学习
    学习记录第一部分Java基础第一章Java概述程序:为执行某些操作或解决某个问题而编写的一系列有序指令的集合。1.java重要特点面向对象(OOP)健壮跨平台性(一次编译......
  • MogDB 学习笔记之 -- PITR恢复
    #概念描述##背景信息当数据库崩溃或希望回退到数据库之前的某一状态时,MogDB的即时恢复功能(Point-In-TimeRecovery,简称PITR)可以支持恢复到备份归档数据之后的任意时间点......
  • MogDB 学习笔记之 --exchange partition
    #概念描述MogDB提供了从分区交换的功能,如单表转化到一个分区中基本语法:ALTERTABLE...EXCHANGEPARTITION数据库版本#测试验证##1、环境准备```miao=>selectversio......
  • global与nonlocal关键字、函数名的多种用法、函数的嵌套调用、函数的嵌套定义、闭包函
    目录一、global与nonlocal关键字二、函数名的多种用法三、函数的嵌套调用四、函数的嵌套定义五、闭包函数六、装饰器简介一、global与nonlocal关键字global方法:用于局部......
  • PLSQL ROW_NUMBER() OVER()函数的使用
    语法格式:row_number()over(partitionby分组列orderby排序列desc)row_number()over()分组排序功能:在使用row_number()over()函数时候,over()里头的分组以及排序......
  • Java并发编程学习15-任务关闭(下)
    任务关闭(下)《任务关闭》由于篇幅较多,拆分了两篇来介绍各种任务和服务的关闭机制,以及如何编写任务和服务,使它们能够优雅地处理关闭。1.处理非正常的线程终止我们知道,当......
  • 学习笔记285—docker 容器基础技术:linux cgroup 简介
    docker容器基础技术:linuxcgroup简介Linuxcgroups的全称是LinuxControlGroups,它是Linux内核的特性,主要作用是限制、记录和隔离进程组(processgroups)使用的物理资......
  • 学习Pinia
    前言全局状态管理工具Pinia.js有如下特点:完整的ts的支持;足够轻量,压缩后的体积只有1kb左右;去除mutations,只有state,getters,actions;actions支持同步和异步;代码......