NASM在线运行

版本:
运行结果
教程手册
代码仓库
极速运行
交互输入
极速运行模式,不支持键盘输入语句但是拥有更高的运行速度,输出简洁明了 。 点击编辑器上方的运行按钮即刻体验吧。
以下是用户最新保存的代码
计算字符串长度 发布于:2021-05-04 08:50 Hello, world! 发布于:2021-05-04 08:41 [更多]
显示目录

子程序功能



子程序功能

它们是可重用的代码段,您的程序可以调用它们来执行各种可重复的任务。子例程使用标签声明,就像我们以前使用的(例如。_start:)然而,我们不使用JMP指令到达它们-相反,我们使用一个新的指令CALL。在运行函数之后,我们也不使用JMP指令返回程序。要从子例程返回到我们的程序,我们使用指令RET代替。

为什么我们不使用JMP来实现子程序呢?

编写子程序的好处是我们可以重用它。如果我们想要在代码的任何地方使用子例程,我们就必须编写一些逻辑来确定我们从代码的哪个位置跳转以及应该跳转到哪个位置。这将使我们的代码充满不必要的标签。然而,如果我们使用CALL和RET,程序集就会使用称为堆栈的东西来处理这个问题。

堆栈简介

堆栈是一种特殊类型的内存。这是我们之前使用过的相同类型的内存,但是它在我们的程序中是特殊的。栈就是所谓的后进先出内存(LIFO)。你可以把它想象成厨房里的一堆盘子。你放的最后一个盘子也是你下次用盘子的时候拿下来的第一个盘子。

堆栈在汇编中不存储板,但它的存储值。您可以在堆栈上存储很多东西,比如变量、地址或其他程序。当调用子例程临时存储稍后将恢复的值时,我们需要使用堆栈。

你的函数需要使用的任何寄存器都应该使用PUSH指令将其当前值放在堆栈上以安全保存。然后,在函数完成其逻辑之后,这些寄存器可以使用POP指令恢复其原始值。这意味着寄存器中的任何值在调用函数之前和之后都是相同的。如果我们在子例程中处理这一点,我们就可以调用函数,而不用担心它们对寄存器做了什么改变。

CALL和RET指令也使用堆栈。当你调用一个子程序时,你在程序中调用它的地址被压入堆栈。然后RET将该地址从堆栈中弹出,程序将跳回代码中的那个位置。这就是为什么你应该总是JMP标签,但你应该调用函数。

; Hello World Program (Subroutines)
; Compile with: nasm -f elf helloworld-len.asm
; Link with (64 bit systems require elf_i386 option): ld -m elf_i386 helloworld-len.o -o helloworld-len
; Run with: ./helloworld-len

SECTION .data
msg     db      'Hello, brave new world!', 0Ah

SECTION .text
global  _start

_start:

    mov     eax, msg        ; move the address of our message string into EAX
    call    strlen          ; call our function to calculate the length of the string

    mov     edx, eax        ; our function leaves the result in EAX
    mov     ecx, msg        ; this is all the same as before
    mov     ebx, 1
    mov     eax, 4
    int     80h

    mov     ebx, 0
    mov     eax, 1
    int     80h

strlen:                     ; this is our first function declaration
    push    ebx             ; push the value in EBX onto the stack to preserve it while we use EBX in this function
    mov     ebx, eax        ; move the address in EAX into EBX (Both point to the same segment in memory)

nextchar:                   ; this is the same as lesson3
    cmp     byte [eax], 0
    jz      finished
    inc     eax
    jmp     nextchar

finished:
    sub     eax, ebx
    pop     ebx             ; pop the value on the stack back into EBX
    ret                     ; return to where the function was called
~$ nasm -f elf helloworld-len.asm
~$ ld -m elf_i386 helloworld-len.o -o helloworld-len
~$ ./helloworld-len
Hello, brave new world!
由JSRUN为你提供的NASM在线运行、在线编译工具
        JSRUN提供的NASM在线运行,NASM 在线运行工具,基于linux操作系统环境提供线上编译和线上运行,具有运行快速,运行结果与常用开发、生产环境保持一致的特点。

title

使用此草稿 删除草稿

皮肤:

运行模式:

嵌入代码 iframe嵌入: