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

68000汇编实战01-编程基础

文章目录

  • 简介
    • 产生背景
    • 应用领域
  • 语言学习
    • EASy68K
      • 帮助文档
      • IDE使用
    • 编程语言
      • comments
      • labels
        • 开始标签
        • 指令标签
        • 位置标签
      • opcode 操作码
        • 常用操作码
          • 数据传送
          • 算术运算
          • 逻辑运算
          • 控制流
            • 分支跳转
            • 地址跳转
            • 子程序跳转
          • 位操作
          • 比较
          • 堆栈操作
        • IO操作码
        • 其他操作码
      • directives 指令
        • DC指令
        • EQU 指令
        • SET 指令
        • DS 指令
        • 其他指令
      • 寄存器
        • 程序计数器(PC)
        • 状态寄存器(SR)
          • 状态寄存器的结构
          • 状态寄存器的作用
          • 示例
        • 数据寄存器(D)
          • D 寄存器的特点
          • D 寄存器的使用场景
          • 示例
        • 地址寄存器(A)
          • A 寄存器的特点
          • A 寄存器的使用场景
          • 示例
        • 堆栈寄存器(SS)
          • 堆栈操作
          • std函数模拟
      • 案例(9*9乘法表)

简介

68000 汇编语言是为 Motorola 68000 微处理器设计的低级编程语言。68000 微处理器于 1979 年推出,因其强大的性能和灵活的架构而广泛应用于多种计算机系统和嵌入式设备中。以下是对 68000 汇编语言的背景、应用领域以及学习它的好处的详细介绍。

产生背景

  1. 技术进步

    • 68000 微处理器是 16 位架构,具有 32 位的地址总线,能够寻址高达 4GB 的内存。这使得它在当时的微处理器中具有较高的性能和灵活性。
    • 其设计采用了复杂指令集计算(CISC)架构,支持多种寻址模式和丰富的指令集。
  2. 市场需求

    • 1970 年代末和1980年代初,个人计算机和嵌入式系统的需求迅速增长。68000 微处理器因其性能和成本效益被广泛采用。
    • 许多知名的计算机系统(如 Apple Macintosh、Atari ST 和 Sega Genesis)都使用了 68000 处理器。

应用领域

  1. 个人计算机

    • 68000 微处理器被用于早期的个人计算机,如 Apple Macintosh 和 Atari ST。这些系统的操作系统和应用程序通常使用 68000 汇编语言进行开发。
  2. 嵌入式系统

    • 68000 处理器也被广泛应用于嵌入式系统,如工业控制、汽车电子和消费电子产品。
  3. 游戏机

    • Sega Genesis 和其他游戏机使用 68000 处理器,许多经典游戏都是用 68000 汇编语言编写的,学习后可以做一些hackrom的实战。
  4. 实时系统

    • 由于其高效的性能,68000 处理器在实时系统中也得到了应用,如医疗设备和航空航天系统。

语言学习

EASy68K

EASy68K 是一个 68000 结构化汇编语言集成开发环境(IDE)。EASy68K 允许您在 Windows PC 或 Wine 上编辑、汇编和运行 68000 程序。无需额外的硬件。EASy68K 是一个开源项目,根据 GNU 通用公共使用许可分发。
使用easy68k方便我们学习整套68000的编程和调试,学习这件基础知识,对我们hackrom或者逆向的基础。
下载地址:http://www.easy68k.com/files/SetupEASy68K.exe
安装完成后的目录结构
在这里插入图片描述

帮助文档

helm.chm提供了完整的编程和调试工具以及68k语言的学习入门资料,可以直接从该文档入手。
在这里插入图片描述

IDE使用

打开EDIT68K.exe,菜单file->new x68 source file 。
在source里面实现一个功能,打印helloworld,并从空值台输入一个字符串并打印。

关于指令,标签,寄存器其他相关的内容请移步后续章节。

源代码

*-----------------------------------------------------------
* Title      :
* Written by :
* Date       :
* Description:
*-----------------------------------------------------------ORG    $1000 ;告诉编译器代码从1000位置开始,不指定默认从0开始
START:                  ; first instruction of program* 将text字符串地址写给A1lea text,A1* 将14号task print 给d0,并执行,14号任务自动获取A1地址的数据并打印move #14,D0trap #15* 执行2号任务,从输入流获取输入,自动写入到A1move #2,D0trap #15* 打印A1地址内容move #14,D0trap #15* Put program code here
*-----------------------------------------------------------
*HELLO:这是一个标签,标识字符串数据的起始位置。
*DC.B:这是一个伪指令,表示“定义常量(Define Constant)”,后面的 .B 表示定义的是字节(Byte)数据。
*'Hello World':这是一个字符串常量,表示字符数组。每个字符占用一个字节。
*$D:这是一个十六进制常量,表示一个字节的值。$D 的十进制值是 13,通常表示回车符(Carriage Return)。
*$A:这是一个十六进制常量,表示一个字节的值。$A 的十进制值是 10,通常表示换行符(Line Feed)。
*0:这是一个字节的值,表示字符串的结束符(null terminator),在 C 语言中常用来标识字符串的结束。
*-----------------------------------------------------------    
text dc.b  'helloworld',0SIMHALT             ; halt simulator* Put variables and constants hereEND    START        ; last line of source

点击工具栏运行按钮(如果由错误会有提示,根据情况修正)
在这里插入图片描述
会弹出一个确认框
在这里插入图片描述
点击execute
在这里插入图片描述
绿色圈圈点击变成红色可下断点,F9运行,F8 stepover,F7 stepinto,点击运行可调试。
在这里插入图片描述

在view可打开内存窗口,栈窗口等
在这里插入图片描述

编程语言

汇编语言程序由以下部分组成:

  • labels 标签 - 用户创建的名称,用于标记程序中的位置。
  • opcode 操作码 - 微处理器可以执行的特定指令,比如ADD,MOVE等。
  • operands 操作数 - 某些指令所需的附加数据,比如#1表示10进制立即数1,$1表示16进制的1。
  • directives 指令 - 发给汇编器的命令,比如ORG $1000,告诉编译器,代码的开始位置,代码段不占用空间,类似于c语言的宏,编译阶段使用。
  • macros 宏 - 用户创建的源代码集合,可以在编写程序时轻松重用。
  • comments 注释 - 用户创建的文本字符串,用于记录程序。
  • 寄存器:汇编语言编程需要与微处理器进行直接交互。68000 微处理器包含八个数据寄存器 D0 到 D7。数据寄存器是通用的,可以视为 8 位、16 位或 32 位的整数变量。还有八个地址寄存器 A0 到 A7,地址寄存器的长度为 32 位。它们通常用于引用变量。状态寄存器(SR)包含状态标志,用于指示比较的结果。

以下是一个例子
在这里插入图片描述

comments

在 Motorola 68000(68k)汇编语言中,注释用于帮助程序员理解代码的功能和逻辑。68k 汇编语言的注释格式如下:(*或者;开头的为注释)

* Date    
TRAP #15  ;将3任务执行,自动打印D1的内容

labels

标签用于通过名称标识程序中的位置或内存位置。需要位置的指令或指令可以使用标签来指示该位置。标签通常在行的第一列开始,必须以空格、制表符或冒号结束。如果使用冒号,它不会成为标签的一部分。如果标签没有在第一列开始,则必须以冒号结束。标签的前 32 个字符是有效的。标签有两种类型:全局标签和局部标签。

全局标签可以在程序的任何地方被引用。因此,全局标签必须是唯一的名称。全局标签应以字母开头,后面可以跟字母、数字或下划线。局部标签可以在程序中重复使用。局部标签必须以点 ‘.’ 开头,后面可以跟字母、数字或下划线。全局标签定义了局部标签的边界。当定义局部标签时,只有在遇到下一个全局标签之前,才能从局部标签上方或下方的代码中引用它。汇编器通过将局部标签名称附加到前面的全局标签并用冒号 ‘:’ 替换点来创建局部标签的唯一名称。结果名称的前 32 个字符是有效的。

开始标签

标签可以用来指定程序的起始位置。如果标签 START 指定了程序的起始位置,那么 END 指令的写法如下:

START:                    Start of programcodeEND    START
指令标签

标签常常放在某个指令前用来表示,定义变量,标签指向存储数据的首地址。
DC - DC 指令指示汇编器将后续的值放入当前内存位置。该指令有三种形式:DC.B 用于字节数据,DC.W 用于字(16 位)数据,DC.L 用于长(32 位)数据。定义常量指令不应与 C++ 中声明常量混淆。
例如

       ORG    $1000              start of the data region 
depart DC.B   'depart.wav',0     stores as a NULL terminated string in consecutive bytes DC.L   $01234567          the value $01234567 is stored as a long wordDC.W   1,2                two words are stored as $0001 and $0002DC.L   1,2                two long words are stored as $00000001 and $00000002 

depart 就是一个label是这块内存区域的首地址。

内存结果

00001000  64 65 70 61 72 74 2E 77 61 76 00 
0000100C  01234567 
00001010  0001 0002 
00001014  00000001 00000002

其他关于指令标签的用法参考,也可以到指令章节:
在这里插入图片描述

位置标签

可以定义一些位置标签,当进行特殊操作时,可以通过控制流opcode跳转到位置标签
实现一个从0,end_index的循环打印

    ORG    $1000
START:                  ; first instruction of program* Put program code here
* 实现一个从0,end_index的循环打印move #1,D1
t:move #3,D0TRAP #15  ;将3任务执行,自动打印D1的内容add.b #1,d1  ;让d1+1CMP #end_index,d1 ;比较d1和end_index的值BNE t  ;如果不相等继续跳转到t label执行SIMHALT             ; halt simulator* Put variables and constants here
end_index equ 10END    START        ; last line of source

opcode 操作码

在 68K 汇编语言中,操作码(opcode)是指令的核心部分,定义了要执行的操作。以下是一些常用的 68K 操作码及其功能:

常用操作码

注意大部分操作码都可以添加结尾.W表示字(2个字节16位).L表示双字(4个字节32位),.B(1个字节8位)

数据传送
- `MOVE`:将数据从一个位置移动到另一个位置。- 例:`MOVE.W D0, D1`(将 D0 的值移动到 D1)
- `MOVEA`:将地址从一个位置移动到另一个位置。- 例:`MOVEA.L A0, A1`(将 A0 的地址移动到 A1)
算术运算
- `ADD`:将两个操作数相加。- 例:`ADD.W D0, D1`(将 D0 的值加到 D1)
- `SUB`:从一个操作数中减去另一个操作数。- 例:`SUB.W D1, D0`(从 D0 中减去 D1)
- `MULS`:有符号乘法。- 例:`MULS D0, D1`(将 D0 和 D1 相乘,结果存储在 D1)
- `DIVS`:有符号除法。- 例:`DIVS D0, D1`(将 D1 除以 D0,结果存储在 D1)
逻辑运算
- `AND`:按位与运算。- 例:`AND.W D0, D1`(D1 与 D0 按位与)
- `OR`:按位或运算。- 例:`OR.W D0, D1`(D1 与 D0 按位或)
- `EOR`:按位异或运算。- 例:`EOR.W D0, D1`(D1 与 D0 按位异或)
- `NOT`:按位取反。- 例:`NOT.W D0`(D0 的值取反)
控制流
常用如下:
- `BRA`:无条件跳转。- 例:`BRA label`(跳转到指定标签)
- `BEQ`:如果相等则跳转。- 例:`BEQ label`(如果零标志位被设置,则跳转)
- `BNE`:如果不相等则跳转。- 例:`BNE label`(如果零标志位未设置,则跳转)
- `JSR`:跳转到子程序。- 例:`JSR subroutine`(跳转到子程序并保存返回地址)
- `RTS`:从子程序返回。- 例:`RTS`(返回到调用子程序的地址)
分支跳转

该指令将在程序中引发分支,如果某些标志被设置。共有十五种检查标志的方法。每种方法都有一个由两个字母组成的符号,用于替换 “cc” 在 “Bcc” 中。

  • BCC:分支如果进位标志清除 - 当 C 标志为 0 时分支。
  • BCS:分支如果进位标志设置 - 当 C 标志为 1 时分支。
  • BEQ:分支如果相等 - 当 Z 标志为 1 时分支。
  • BNE:分支如果不相等 - 当 Z 标志为 0 时分支。
  • BGE:分支如果大于或等于 - 当 N 和 V 相等时分支。
  • BGT:分支如果大于 - 当 N 和 V 相等且 Z=0 时分支。
  • BHI:分支如果高于 - 当 C 和 Z 都为 0 时分支。
  • BLE:分支如果小于或等于 - 当 Z=1 或 N 和 V 不同时分支。
  • BLS:分支如果小于或相同 - 当 C=1 或 Z=1 时分支。
  • BLT:分支如果小于 - 当 N 和 V 不同时分支。
  • BMI:分支如果负 - 当 N=1 时分支。
  • BPL:分支如果正 - 当 N=0 时分支。
  • BVC:分支如果溢出标志清除 - 当 V=0 时分支。
  • BVS:分支如果溢出标志设置 - 当 V=1 时分支。
  • BRA:无条件分支 - 始终分支。

上面这些opcode根据标志触发跳转,只能跳转到label,注意进入label后会往下执行,和函数调用不一样,函数调用会返回,继续执行之前代码的下一行,这个不会,是直接跳转过去不回来了。

例子:

    ORG    $1000
START:                  ; first instruction of program* Put program code here
input:move.b #4,d0TRAP #15CMP #0,d1BNE input ;如果不等于0跳转到input标签,继续让输入数字BEQ exit  ;如果等于0直接退出labelexit:SIMHALT             ; halt simulator* Put variables and constants hereEND    START        ; last line of source
地址跳转

JMP(跳转)用于将程序控制转移到一个有效地址。它实际上相当于 MOVE.L xxx, PC,因为它将程序计数器更改为一个有效地址(计算得出)。

注意JMP是无条件跳转,相对于B开头的跳转,他也支持 JMP label的语法,同时他也支持直接JMP 地址的跳转。

    ORG    $1000
START:                  ; first instruction of program* Put program code here
input:move.b #4,d0TRAP #15CMP #0,d1BNE  input ;如果不等于0跳转到input标签,继续让输入数字BEQ exit  ;如果等于0直接退出labelexit:LEA quit,a0 ;=0跳转到这里后,将quit的地址给到a0,JMP直接跳转到地址,相当于:move.l a0,PC(这是伪代码)JMP (a0) ;如果想跳转到a0的下一个地址,可以1(a0) 或者n(a0),当然也可以直接JMP quitquit:SIMHALT             ; halt simulator* Put variables and constants hereEND    START        ; last line of source
子程序跳转

JSR/BSR(跳转到子例程)与 JMP(无条件跳转)类似,但在跳转之前,JSR 会将跳转指令后面的地址压入栈中,这样可以通过 RTS(返回子例程)指令返回,也就相当于调用函数,函数执行完了,执行代码的下一行。

BSR适合同一代码段里的label直接调用,是相对掉哟个,JSR适合指定一个绝对地址调用(比如JSR $5000) ,但是实际上两个可以互相替换,没啥区别。

    ORG    $1000
START:                  ; first instruction of program* Put program code here
input:JSR input_notion  ;JSR执行完后会自动执行下一行代码,B开头的跳过去就不回来了move.b #4,d0TRAP #15CMP #0,d1BNE  input ;如果不等于0跳转到input标签,继续让输入数字BEQ exit  ;如果等于0直接退出
input_notion: ;屏幕上输出提示语MOVE    #14,D0LEA        INPUT_STR,A1TRAP        #15RTS  ;注意返回了会运行调用这个函数的下一行
confirm_exit      *屏幕上输出确认提示语MOVE    #14,D0LEA        CONFIRM_STR,A1TRAP        #15RTS
exit:JSR confirm_exitmove.b #4,d0TRAP #15CMP #0,d1BEQ quitBNE input
quit:SIMHALT             ; halt simulator* Put variables and constants here
INPUT_STR: dc.b 'please input number(exit=0):',0
CONFIRM_STR: dc.b 'confirm exit(:exit=0,not=1):',0END    START        ; last line of source

效果
在这里插入图片描述

位操作
- `SHL`:左移。- 例:`SHL.W #1, D0`(D0 左移 1 位)
- `SHR`:右移。- 例:`SHR.W #1, D0`(D0 右移 1 位)
- `ROL`:循环左移。- 例:`ROL.W #1, D0`(D0 循环左移 1 位)
- `ROR`:循环右移。- 例:`ROR.W #1, D0`(D0 循环右移 1 位)
比较
- `CMP`:比较两个操作数。- 例:`CMP.W D0, D1`(比较 D0 和 D1 的值)
堆栈操作
- `PUSH`:将数据压入堆栈。- 例:`PUSH.W D0`(将 D0 的值压入堆栈)
- `POP`:从堆栈弹出数据。- 例:`POP.W D0`(从堆栈弹出值到 D0)
IO操作码

TRAP #15 被用于触发 I/O. 不同的io流任务存储在: D0.
参考chm:
在这里插入图片描述
常用的输入输出任务:

  • 14: 将A1地址对应的字符串输出 以0结尾结束。
  • 13:将A1地址对应的字符串输出 以0结尾结束,加上\r\n换行。
  • 2: 从控制台获取一个字符串回车后存储在A1地址中 0结尾。
  • 4:读取一个数字写入D1.L中。

例子

START   ORG     $1000   Program load address.move    #14,D0 ;设置14号任务打印A1地址字符串lea     text,A1  ;获text地址到A1trap    #15     ;激活任务SIMHALT        text    dc.b    'Hello World',0   ;0表示字符串结束END     START   End of source with start address specified.
其他操作码

关于更加详情的指令参考chm
在这里插入图片描述

directives 指令

指令是汇编器需要遵循的指令。它们占据源代码行中的第二个字段,与指令操作码占据的位置相同,但指令并不是 68000 操作码。 “DC” 和 “DCB” 是唯一会导致数据被添加到输出文件中的指令。指令还可以用于控制宏的汇编、条件汇编和结构化语法。

在以下描述中,选项项用方括号 [] 表示。用斜体显示的项应替换为适当的语法。

Usage:
[label] directive[.size] [data,data,...]^                 ^         ^\_________________\_________\_____ varies by directive
DC指令
  • 全称:Define Constant(定义常量)
  • 用途:用于定义并初始化数据常量。DC 指令可以用于定义一个或多个初始值,这些值会被存储在程序的输出文件中。
  • 内存分配DC 指令会在程序的内存中分配实际的存储空间,并将指定的值写入该空间。
  • 示例
    使用语法:
Usage:
[label] DC.size data,data,...

例子:

VALUE1 DC 10          ; 定义常量 VALUE1,值为 10
VALUE2 DC 20, 30      ; 定义常量 VALUE2,值为 20 和 30
  • 特性
    • 定义的值在程序运行时是不可更改的。
    • 实际在内存中占用空间。

注意下面的代码修改地址的值是非法的,常量无法修改

START:                  ; first instruction of programlea usercount,A0move.b 20,(A0) ;修改A0地址的常量这是非法的。
* Put program code hereSIMHALT             ; halt simulator* Put variables and constants hereORG    $1200
usercount    dc.b    10,20dc.w    23

在这里插入图片描述

EQU 指令
  • 全称:Equate(等于)

  • 用途:用于定义一个符号并将其与一个值关联。EQU 定义的值在整个程序中是不可更改的,通常用于定义常量或符号地址,类似于c语言的#define在预编译将对应引用的地方替换为值。

  • 内存分配EQU 不会在内存中分配实际的存储空间。它只是创建一个符号,所有使用该符号的地方都会被替换为其定义的值。

  • 示例

    MAX_SIZE EQU 100 ; 定义常量 MAX_SIZE,值为 100

  • 特性

    • 一旦定义,EQU 的值不能被修改。
    • 不占用内存空间,编译时进行替换
        ORG    $1000          ; 程序起始地址
START:           ; 将立即数 10 移动到 D0 寄存器; 定义常量
MAX_COUNT EQU 2              ; 定义 MAX_COUNT 为 100
START_VALUE EQU 1             ; 定义 START_VALUE 为 10MOVE.B #10, D0ADD.B #MAX_COUNT, D0     ; 将 MAX_COUNT (100) 加到 D0SUB.B #START_VALUE, D0    ; 将 START_VALUE (10) 从 D0 中减去SIMHALT                  ; 停止模拟器ORG    $1200            ; 数据段起始地址END    START

在这里插入图片描述

SET 指令
  • 用途:用于定义一个符号并赋予一个初始值,但与 DC 不同的是,SET 定义的值是可更改的。SET 通常用于在程序运行时动态地改变值。

  • 示例

    COUNT SET 0 ; 定义符号 COUNT,初始值为 0 COUNT SET COUNT + 1 ; 重新定义 COUNT,值为 COUNT + 1

  • 内存分配SET 指令并不分配实际的存储空间来存储值,而是定义一个符号,允许在程序中动态地改变该符号的值。

DS 指令
  • 全称:Define Space(定义空间)

  • 用途:用于定义一块未初始化的内存空间。DS 指令只分配内存,但不初始化这些内存的值,随时可改。

  • 示例

    BUFFER DS 256 ; 定义一个大小为 256 字节的缓冲区

  • 内存分配DS 指令会在输出文件中分配指定大小的内存空间,但这些空间的初始值是未定义的(通常是随机值或零,具体取决于系统)。

定义一个100字节的空间,可以理解为数组,将MULT_TABLE数字第一个位置设置为:12

    ORG    $1000
START:                  ; first instruction of program* Put program code heremove.B #0,D0LEA MULT_TABLE, A0MOVE.B #12,(A0, D0)SIMHALT             ; halt simulatorORG    $1200
* Put variables and constants hereMULT_TABLE:        ; 乘法表的存储位置DS.B 10 * 10   ; 预留 10x10 的空间END    START        ; last line of source
其他指令

参考chm
在这里插入图片描述

寄存器

程序计数器(PC)

程序计数器(有时在不同的体系结构中也称为指令指针或指令地址寄存器)保存下一条将要执行的指令的内存地址。每当 CPU 执行一条指令时,PC 的值会自动更新,以指向下一条指令。
更新机制:在大多数情况下,PC 在指令执行后自动加一(或加上指令的长度),以指向下一条指令的地址。
编写一个简单程序 运行,默认会从start:的写一条语句开始,PC寄存器指向初始代码的地址(注意有效的代码时左侧绿色点点的,其他都是指令或者注释)
在这里插入图片描述
按下F8执行到下一条
在这里插入图片描述
我这里将usercount的地址指向A0 ,同时加了ORG $1200从1200这个地址写入。点击A0的地址可以查看内存:
在这里插入图片描述

状态寄存器(SR)

在 68k(Motorola 68000)架构中,状态寄存器(SR,Status Register)是一个重要的寄存器,用于存储处理器的状态信息和控制标志。状态寄存器的内容影响程序的执行流程,特别是在条件跳转和中断处理时。以下是对 68k 状态寄存器的详细介绍:

状态寄存器的结构

68k 的状态寄存器是一个 16 位的寄存器,包含多个标志位。主要的标志位包括:

  1. N(Negative):

    • 表示最近一次运算的结果是否为负数。
    • 如果结果的最高位(符号位)为 1,则 N 标志被设置。
  2. Z(Zero):

    • 表示最近一次运算的结果是否为零。
    • 如果结果为 0,则 Z 标志被设置。
  3. V(Overflow):

    • 表示最近一次运算是否发生了溢出。
    • 溢出通常发生在有符号数运算中,当结果超出可表示的范围时,V 标志被设置。
  4. C(Carry):

    • 表示最近一次运算是否产生了进位或借位。
    • 在加法运算中,如果产生了进位,C 标志被设置;在减法运算中,如果发生了借位,C 标志也会被设置。
  5. I(Interrupt Mask):

    • 这是一个 3 位的中断屏蔽位,控制中断的响应。
    • I0、I1 和 I2 位用于设置中断优先级,值越大,响应的中断优先级越低。
  6. T(Trace):

    • 这是一个单个位,用于启用或禁用跟踪模式。
    • 当 T 位被设置时,处理器将在每个指令执行后产生一个中断,适用于调试。
  7. S(Supervisor):

    • 这是一个单个位,指示当前处理器是否处于特权模式(超级用户模式)。
    • 当 S 位被设置时,处理器处于超级用户模式,允许执行特权指令。
状态寄存器的作用
  • 条件跳转: 状态寄存器中的标志位用于条件跳转指令(如 BEQBNE 等),根据运算结果的状态决定程序的执行路径。
  • 中断处理: 中断标志位控制中断的响应,允许或禁止特定级别的中断。
  • 运算结果的状态: 通过检查 N、Z、V 和 C 标志,程序可以根据运算结果的状态做出相应的处理。
示例

以下是一个简单的示例,展示如何使用状态寄存器的标志位:

    MOVE.L #5, D0          ; 将 5 加载到 D0MOVE.L #3, D1          ; 将 3 加载到 D1SUB.L D1, D0           ; D0 = D0 - D1,结果为 2; 检查 Z 标志BEQ zero_result        ; 如果 Z 标志为 1,跳转到 zero_result; 检查 N 标志BPL positive_result     ; 如果 N 标志为 0,跳转到 positive_resultzero_result:; 处理结果为零的情况; ...positive_result:; 处理结果为正的情况; ...
数据寄存器(D)

在 68000(68k)架构中,D 寄存器(数据寄存器)是用于存储数据和操作数的寄存器。68k 处理器有 8 个数据寄存器,分别为 D0 到 D7。

D 寄存器的特点
  1. 数量:

    • 68k 处理器有 8 个数据寄存器,编号为 D0 到 D7。
  2. 大小:

    • 每个 D 寄存器的大小为 32 位(4 字节),可以存储 32 位的整数或指针。
  3. 用途:

    • D 寄存器主要用于存储运算的操作数、结果以及临时数据。它们在算术运算、逻辑运算、数据传输等操作中被广泛使用。
  4. 寻址模式:

    • D 寄存器可以与多种寻址模式结合使用,支持直接寻址、间接寻址等方式,方便数据的访问和操作。
  5. 操作:

    • D 寄存器可以参与各种指令的操作,如加法、减法、位运算等。指令可以直接对 D 寄存器进行操作,也可以将 D 寄存器的值存储到内存中或从内存中加载数据。
D 寄存器的使用场景
  • 算术运算: D 寄存器用于存储参与运算的数值。
  • 数据传输: 在数据传输指令中,D 寄存器可以作为源或目标。
  • 函数参数: 在调用子程序时,D 寄存器常用于传递参数。
示例

以下是一个简单的汇编代码示例,展示如何使用 D 寄存器进行基本的算术运算:

    MOVE.L #10, D0        ; 将 10 加载到 D0 寄存器MOVE.L #5, D1         ; 将 5 加载到 D1 寄存器ADD.L D1, D0          ; D0 = D0 + D1,D0 现在为 15
地址寄存器(A)

68000(68k)架构中,A 寄存器(地址寄存器)是用于存储内存地址的寄存器。68k 处理器有 8 个地址寄存器,分别为 A0 到 A7。以下是对 A 寄存器的详细描述:

A 寄存器的特点
  1. 数量:

    • 68k 处理器有 8 个地址寄存器,编号为 A0 到 A7。
  2. 大小:

    • 每个 A 寄存器的大小为 32 位(4 字节),可以存储 32 位的内存地址。
  3. 用途:

    • A 寄存器主要用于存储内存地址,支持数据的加载和存储操作。它们在指令中用于指向数据或指令的内存位置。
  4. 寻址模式:

    • A 寄存器可以与多种寻址模式结合使用,包括直接寻址、间接寻址、基址寻址和相对寻址等。这使得程序能够灵活地访问内存中的数据。
  5. 堆栈指针:

    • A7 寄存器通常用作堆栈指针(SP),指向当前堆栈的顶部。堆栈用于存储函数调用的返回地址、局部变量等。
A 寄存器的使用场景
  • 内存访问: A 寄存器用于指向数据在内存中的位置,支持数据的读取和写入。
  • 函数调用: 在函数调用中,A 寄存器可以用于传递参数和返回地址。
  • 堆栈管理: A7 寄存器作为堆栈指针,管理函数调用的堆栈帧。
示例

以下是一个简单的汇编代码示例,展示如何使用 A 寄存器进行内存操作:

   LEA array, A0         ; 将数组的地址加载到 A0 寄存器MOVE.L (A0), D0       ; 从 A0 指向的地址加载数据到 D0 寄存器ADD.L #1, D0          ; D0 = D0 + 1MOVE.L D0, (A0)       ; 将 D0 的值存储回 A0 指向的地址
堆栈寄存器(SS)

在68k架构中,堆栈寄存器是用于管理程序运行时的堆栈的关键组件。68k系列处理器使用一个专用的寄存器来指向当前堆栈的顶部,这个寄存器被称为堆栈指针(Stack Pointer)。

在68k架构中,堆栈指针寄存器通常是 A7(地址寄存器7),它指向当前堆栈的顶部。
堆栈是一个后进先出(LIFO)的数据结构,用于存储临时数据,如函数调用的返回地址、局部变量和中断处理程序的上下文。

在这里插入图片描述

堆栈操作

我们来看下堆栈指针的移动和数据写入逻辑。
在68k汇编语言中,-(A7) 和 (A7)+ 分别用于表示压栈和出栈操作。
执行代码

move.l #10,-(a7)

未执行前原始堆栈地址A7指向:01000000,没有任何数据
在这里插入图片描述
执行:move.l #10,-(a7)
在这里插入图片描述
执行:move.l #20,-(a7)
在这里插入图片描述
执行出栈:move.l (a7)+,d0
在这里插入图片描述

std函数模拟

我们知道c语言的std约定是:调用函数先压入执行代码的后一个位置,然后参数从右往左压入,在函数内部出栈从左(后入先出)往右获取参数,执行完成获取代码执行的位置,跳转。
我们来模拟这个过程:
假设函数:
public int add(int a,int b)
用98k模拟堆栈实现:

    ORG    $1000
START:                  ; first instruction of program* Put program code heremove.l #10,-(a7) #第二个参数压栈。move.l #20,-(a7) #第一个参数压栈。LEA *+12, A0  *计算下LEA占用4个字节,一直到move.l d0,d2是12个字节,*+12就是从PC当前位置+12个就是下一个执行代码的位置move.l a0,4(a7) *将下一个执行的地址压栈JMP addmove.l d0,d2SIMHALT             ; halt simulatoradd:move.l (a7)+,a0  ;地址出栈move.l (a7)+,d0 ;第一个参数出栈move.l (a7)+,d1 ;第二个参数出栈add.l d1,d0JMP (a0)* Put variables and constants hereEND    START        ; last line of source

案例(9*9乘法表)

*-----------------------------------------------------------
* Title      :
* Written by :
* Date       :
* Description:
*-----------------------------------------------------------ORG    $1000
START:                  ; first instruction of program* Put program code heremove.b #start_index,d2 ;行索引move.b #start_index,d3  ;列索引
row:jsr print_str_line ;到row的部分就添加一个换行,jsr调用子程序,子程序需要RTS返回add.b #1,d2 ;每运行一次+1move.b #start_index,d3cmp #end_index+1,d2 ;到达最后一行+1直接退出BEQ exitcol:add.b #1,d3move.b d2,d1jsr print_num ;打印行的数字lea tmp_str,a1move.b #'*',(a1) ;打印一个*jsr print_strmove.b d3,d1jsr print_num ;打印一个列的数字move.b #'=',(a1) jsr print_str ;打印一个=move.b #1,d4muls d2,d4muls d3,d4move.b d4,d1jsr print_num ;打印一个列的数字move.b #' ',(a1) jsr print_str ;打印一个空格cmp d3,d2BEQ rowBNE col
print_num:move.b #3,d0TRAP #15 RTS    
print_str:move.b #0,1(a1) ;打印字符的结尾move.b #14,d0TRAP #15 RTS   
print_str_line:move.b #0,(a1) ;打印字符的结尾move.b #13,d0TRAP #15 RTS       
exit:SIMHALT             ; halt simulator* Put variables and constants here
tmp_str ds.b 2
end_index equ 9
start_index equ 0END    START        ; last line of source

效果
在这里插入图片描述

相关文章:

68000汇编实战01-编程基础

文章目录 简介产生背景应用领域 语言学习EASy68K帮助文档IDE使用 编程语言commentslabels开始标签指令标签位置标签 opcode 操作码常用操作码数据传送算术运算逻辑运算控制流分支跳转地址跳转子程序跳转 位操作比较堆栈操作 IO操作码其他操作码 directives 指令DC指令EQU 指令S…...

常见的概念 及 分布式系统的演变过程

文章目录 一. 概念解释1. 应用(Application)/ 系统(System)2. 模块(Module)/ 组件(Component)3. 分布式(Distributed)4. 集群(Cluster&#xff09…...

torch.is_nonzero(input)

torch.is_nonzero(input) input: 输入张量 若输入是 不等于零的单元素张量 则返回True,否则返回False 不等于零的单元素张量:torch.tensor([0.]) 或 torch.tensor([0]) 或 torch.tensor([False])单元素张量: 只有一个数 的张量 import torch print(t…...

爬虫开发(5)如何写一个CSDN热门榜爬虫小程序

笔者 綦枫Maple 的其他作品,欢迎点击查阅哦~: 📚Jmeter性能测试大全:Jmeter性能测试大全系列教程!持续更新中! 📚UI自动化测试系列: SeleniumJava自动化测试系列教程❤ &#x1f4da…...

Rust 组织管理

Rust 组织管理 Rust 是一种系统编程语言,以其安全性、并发性和性能而闻名。随着 Rust 社区的不断壮大,有效的组织管理变得至关重要。本文将探讨 Rust 社区的组织结构、项目管理、社区参与和未来发展方向。 Rust 社区的组织结构 Rust 社区采用了一种去中心化的组织结构。核…...

谈谈微服务的常用组件

由于微服务给系统开发带来了一些问题和挑战,如服务调用的复杂性、分布式事务的处理、服务的动态管理等,为了更好地解决这些问题和挑战,各种微服务治理的组件应运而生,充当微服务架构的基石和支撑,常用组件如下表&#…...

Android11.0默认壁纸缩放

获取壁纸缩放值的代码 //in com.android.server.wm.WallpaperController private final float mMaxWallpaperScale; //construct method WallpaperController(WindowManagerService service, DisplayContent displayContent) {......mMaxWallpaperScale service.mContext.ge…...

git 本地同步远端分支

一、关联远程仓库 本地仓库关联远端仓库 git remote add origin https://github.com/user/repository.git 二、获取远程分支信息 获取远程仓库的最新分支信息 git fetch origin 三、创建或切换到本地分支以跟踪远程分支 1. 创建分支 创建分支并关联到远端分支 git bra…...

数字IC后端设计实现之分段长clock tree经典案例

最近发现很多读者问到分段长clock tree的做法,小编今天给大家分享几个SoC芯片中复杂时钟结构设计的分段长clock tree的应用案例。希望对各位的学习和工作有所助益。 数字后端设计实现之时钟树综合实践篇 数字IC后端实现专家都具备哪些技能?&#xff08…...

矩阵重新排列——rot90函数

通过 r o t 90 rot90 rot90函数可以将矩阵进行旋转 用法: r o t 90 ( a , k ) rot90(a,k) rot90(a,k)将矩阵 a a a按逆时针方向旋转 k 9 0 ∘ k\times90^\circ k90∘...

深入解析音视频流媒体SIP协议交互过程

一、引言 在音视频流媒体传输过程中,SIP(Session Initiation Protocol)协议发挥着举足轻重的作用。本文将详细全面地介绍音视频流媒体传输中的SIP协议,包括其基本概念、交互过程、关键信令以及应用场景 二、SIP协议基本概念 1.…...

【C++】深入解析 cin 和 cout:理解区分输入输出流运算符

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;cin 和 cout 简介&#x1f4af;cin >> 与 cout << 的流运算符&#x1f4af;理解流运算符方向的四种方法1. 符号方向对应数据流动的方向2. 形象比喻3. 记住公式…...

java介绍

Java是一种广泛应用的高级编程语言&#xff0c;具有以下特点和应用场景&#xff1a; 语言特性 简单易学 Java语法相对简洁&#xff0c;去除了一些复杂的指针操作等&#xff0c;使得程序员能够更专注于业务逻辑的实现。例如&#xff0c;Java使用自动内存管理&#xff08;垃圾回…...

1-深度学习干货总结(持续更新)

机器学习核心组件 可以用来学习的数据&#xff08;data&#xff09;&#xff1b; 如何转换数据的模型&#xff08;model&#xff09;&#xff1b; 一个目标函数&#xff08;objective function&#xff09;&#xff0c;用来量化模型的有效性&#xff1b; 调整模型参数以优化…...

《C++搭建神经网络基石:开启智能编程新征程》

在人工智能的璀璨星空中&#xff0c;神经网络无疑是最为耀眼的星座之一。而 C以其卓越的性能和高效的执行效率&#xff0c;成为构建神经网络模型的有力武器。今天&#xff0c;就让我们一同探索如何使用 C构建一个基础的神经网络模型&#xff0c;踏上智能编程的奇妙旅程。 一、…...

小程序 - 本地生活

小程序页面和样式练习 - 本地生活小程序开发笔记 目录 本地生活 准备工作 加载图片素材 页面开发 页面样式开发 功能实现截图 总结 本地生活 本地生活”微信小程序是一个介绍本地美食、装修、工作等信息的微信小程序&#xff0c;该微信小程序的首页包含轮播图区域和九宫…...

docker的joinsunsoft/docker.ui修改密码【未解决】

docker的joinsunsoft/docker.ui修改密码 前言 这个挺遗憾的&#xff0c;个人能力不足。想修改密码是不可能了。 因为&#xff0c;系统的密码加密规则不知道。 目前了解到的内容是&#xff1a; 地址是&#xff1a;https://hub.docker.com/r/joinsunsoft/docker.ui服务是用go语…...

pyspark实现基于协同过滤的电影推荐系统

最近在学一门大数据的课&#xff0c;课程要求很开放&#xff0c;任意做一个大数据相关的项目即可&#xff0c;不知道为什么我就想到推荐算法&#xff0c;一直到着手要做之前还没有新的更好的来代替&#xff0c;那就这个吧。 推荐算法 推荐算法的发展由来已久&#xff0c;但和…...

【VRChat 全身动捕】VIVE 手柄改 tracker 定位器教程,低成本光学动捕解决方案(持续更新中2024.11.26)

更新 0.0.1&#xff08;2024/11/26&#xff09;&#xff1a; 1.解决了内建蓝牙无法识别、“steamVR 蓝牙不可用” 的解决方案 2.解决了 tracker 虽然建立了连接但是在 steamVR 界面上看不到的问题 3.解决了 VIVE 基站1.0 无法被蓝牙识别 && 无法被 steamVR 搜索到 &…...

C++11

C11 C11简介一.列表初始化{ }initializer_list 二.一些关键字三.右值引用和移动语义&#xff08;重要&#xff09;完美转发移动构造和移动赋值重载 四.小知识类成员变量初始化 五.可变参数模板六.lambda表达式&#xff08;又称匿名函数&#xff09;&#xff08;重要&#xff09…...

MySQL - 表的增删查改

文章目录 1.新增1.1语法1.2单行插入1.3多行插入1.4插入后更新1.5替换 2.查找2.1语法2.2使用 3.修改3.1语法3.2使用 4.删除4.1语法4.2使用4.3截断表 5.插入查询结果5.1语法5.2使用 1.新增 1.1语法 INSERT [INTO] table_name [(column1, column2, ...)] VALUES (value1, value2…...

Vue3 调用子组件的方法和变量

1. 通过 ref 调用子组件的方法和变量 Vue 3 引入了 ref&#xff0c;你可以通过 ref 获取子组件实例&#xff0c;并调用其方法或访问其数据。 例子 子组件 (Child.vue) <template><div><p>{{ message }}</p><button click"updateMessage&qu…...

蓝桥杯嵌入式再学习(4)led的点亮

led的点亮的话先在cubemx里点一下配置 以下是对应的代码...

CentOS7安装nvm

CentOS7安装nvm 在 CentOS 7 上安装 NVM&#xff08;Node Version Manager&#xff09;可以通过以下步骤进行。NVM 是一个用于管理多个 Node.js 版本的工具&#xff0c;允许你在不同的项目中使用不同的 Node.js 版本。 步骤 1&#xff1a;更新系统 首先&#xff0c;确保你的…...

2024年工信部大数据分析师证书报考条件是怎样的?有什么用

大数据分析师&#xff0c;乃是这样一类专业人才&#xff0c;他们凭借着先进且高效的数据分析技术以及各类实用工具&#xff0c;对规模庞大、纷繁复杂的海量数据展开全面而细致的清洗、处理、分析以及解读工作。其工作的核心目标在于为企业的决策制定提供有力依据&#xff0c;推…...

天锐绿盾加密软件与Ping32联合打造企业级安全保护系统,确保敏感数据防泄密与加密管理

随着信息技术的飞速发展&#xff0c;企业在日常经营过程中产生和处理的大量敏感数据&#xff0c;面临着越来越复杂的安全威胁。尤其是在金融、医疗、法律等领域&#xff0c;数据泄漏不仅会造成企业巨大的经济损失&#xff0c;还可能破坏企业的信誉和客户信任。因此&#xff0c;…...

代码随想录算法训练营第六十天|Day60 图论

Bellman_ford 队列优化算法&#xff08;又名SPFA&#xff09; https://www.programmercarl.com/kamacoder/0094.%E5%9F%8E%E5%B8%82%E9%97%B4%E8%B4%A7%E7%89%A9%E8%BF%90%E8%BE%93I-SPFA.html 本题我们来系统讲解 Bellman_ford 队列优化算法 &#xff0c;也叫SPFA算法&#xf…...

Web登录页面设计

记录第一个前端界面&#xff0c;暑假期间写的&#xff0c;用了Lottie动画和canvas标签做动画&#xff0c;登录和注册也连接了数据库。 图片是从网上找的&#xff0c;如有侵权私信我删除&#xff0c;谢谢啦~...

Rust标准库中集合类型用法详解

文章目录 Vec<T> 动态数组创建动态数组增加删除元素访问元素遍历Vec控制容量修改元素元素排序 HashMap<K, V>哈希表创建 HashMap插入和更新元素访问元素删除元素遍历HashMap使用默认值 HashSet<T>哈希集合创建 HashSet插入和删除元素查找元素遍历HashSet使用…...

软件测试面试之数据库部分

1.取第 4 到5 条记录 --按ID从小到大&#xff0c;查询第到第条数据 select top4 *from(select top5 * from qicheorder by ID asc ) as TA order by ID desc--按ID从小到大&#xff0c;查询第到第条数据 select top 2*from(select top 4 *from qicheorder by ID asc )as TA o…...

Gitee markdown 使用方法(持续更新)

IPKISS 获取仿真器件的名称 引言正文标题换行第一种------在行末尾手动键入两个空格第二种------额外换行一次&#xff0c;即两行中间留一个空行 缩进与反缩进代码块行内代码添加图片添加超链接 加粗&#xff0c;倾斜&#xff0c;加粗倾斜 引言 有些保密性的文件或者教程&…...

水库大坝安全监测之量水堰计应用

量水堰计是水库大坝安全监测系统中的一种关键设备&#xff0c;主要用于测量水库水位、流量等水力参数。以下是量水堰计在水库大坝安全监测中的应用及注意事项&#xff1a; 一、量水堰计的工作原理 量水堰计是一种专门用于测量水流流量的仪器&#xff0c;其工作原理主要基于水流…...

Mouser EDI 需求分析

为了提高供应链的自动化水平&#xff0c;贸泽电子&#xff08;Mouser Electronics&#xff09;使用EDI技术更好地管理与其全球合作伙伴之间的业务数据往来。对接Mouser EDI&#xff0c;对于企业而言&#xff0c;需要在本地部署EDI软件&#xff0c;建立与Mouser之间的EDI连接通道…...

51单片机快速入门之中断的应用 2024/11/23 串口中断

51单片机快速入门之中断的应用 基本函数: void T0(void) interrupt 1 using 1 { 这里放入中断后需要做的操作 } void T0(void)&#xff1a; 这是一个函数声明&#xff0c;表明函数 T0 不接受任何参数&#xff0c;并且不返回任何值。 interrupt 1&#xff1a; 这是关键字和参…...

电脑显示器拔插DVI线后副屏不显示

问题&#xff1a;台式机副屏显示器插拔DVI线后副屏无法检测到&#xff0c;不显示 其他现象&#xff1a;电脑设备管理器“显示适配器”中只有独显&#xff0c;未显示集显。 尝试方法&#xff1a; 1、 重新插拔并拧紧DVI线、更换DVI线、将DVI线替换为VGA线、调换DVI线及VGA线两…...

git分支管理:release分支内容重置为master

背景&#xff1a;公司项目存在release和master分支&#xff0c;一直是release合并到master分支&#xff1b;由于历史总总原因导致release和master分支内容相差很大。某个夜晚&#xff0c;leader悄悄改了master分支的内容&#xff08;不走合并流程&#xff09;&#xff0c;然后通…...

python之poetry 安装、创建项目、修改源、创建虚拟环境等操作

CentOs7.5下安装python3&#xff0c;修改源&#xff0c;创建虚拟环境 python 虚拟环境的搭建 使用pyenv 管理多个版本的python 安装 pyenv curl https://pyenv.run | bash pyenv install 3.10 pyenv local 3.10 # 当前项目激活Python3.10 pyenv global 3.10 # 当前全部激活P…...

一个高度可扩展的 Golang ORM 库【GORM】

GORM 是一个功能强大的 Golang 对象关系映射&#xff08;ORM&#xff09;库&#xff0c;它提供了简洁的接口和全面的功能&#xff0c;帮助开发者更方便地操作数据库。 1. 完整的 ORM 功能 • 支持常见的关系模型&#xff1a; • Has One&#xff08;一对一&#xff09; • …...

hadoop_HA高可用

秒懂HA HA概述HDFS-HA工作机制工作要点元数据同步参数配置手动故障转移自动故障转移工作机制相关命令 YARN-HA参数配置自动故障转移机制相关命令 附录Zookeeper详解 HA概述 H(high)A(avilable)&#xff1a; 高可用&#xff0c;意味着必须有容错机制&#xff0c;不能因为集群故障…...

23种设计模式-工厂方法(Factory Method)设计模式

文章目录 一.什么是工厂方法设计模式&#xff1f;二. 工厂方法模式的特点三.工厂方法模式的结构四.工厂方法模式的优缺点五.工厂方法模式的 C 实现六.工厂方法模式的 Java 实现七.代码解析八.总结 类图&#xff1a; 工厂方法设计模式类图 一.什么是工厂方法设计模式&#xff1…...

论文笔记 SliceGPT: Compress Large Language Models By Deleting Rows And Columns

欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游。 数学知识 秩&#xff1a; 矩阵中最大线性无关的行/列向量数。行秩与列秩相等。 线性无关&#xff1a;对于N个向量而言&#xff0c;如果任取一个向量 v \textbf{v} v&#xff0c;不能被剩下的N-1个向量通过线性组合的方式…...

构建 LLM (大型语言模型)应用程序——从入门到精通(第七部分:开源 RAG)

通过检索增强生成 (RAG) 应用程序的视角学习大型语言模型 (LLM)。 本系列博文 简介数据准备句子转换器矢量数据库搜索与检索大语言模型开源 RAG&#xff08;本帖&#xff09;评估服务LLM高级 RAG 1. 简介 我们之前的博客文章广泛探讨了大型语言模型 (LLM)&#xff0c;涵盖了其…...

快速理解倒排索引在ElasticSearch中的作用

一.基础概念 定义&#xff1a; 倒排索引是一种数据结构&#xff0c;用来加速文本数据的搜索和检索&#xff0c;和传统的索引方式不同&#xff0c;倒排索引会被每个词汇项与包含该词汇项的文档关联起来&#xff0c;从而去实现快速的全文检索。 举例&#xff1a; 在传统的全文…...

彻底理解微服务配置中心的作用

常见的配置中心有SpringCloudConfig、Apollo、Nacos等&#xff0c;理解它的作用&#xff0c;无非两点&#xff0c;一是配置中心能做什么&#xff0c;不使用配置中心会出现什么问题。 作用&#xff1a;配置中心是用来集中管理服务的配置&#xff0c;它是用来提高系统配置的维护…...

基于YOLOv8深度学习的智慧农业棉花采摘状态检测与语音提醒系统(PyQt5界面+数据集+训练代码)

智慧农业在现代农业中的应用日益广泛&#xff0c;其核心目标是通过智能化手段实现农业生产的自动化、精准化和高效化&#xff0c;而精准采摘技术作为智慧农业的重要组成部分&#xff0c;正受到越来越多的关注。棉花作为一种经济作物&#xff0c;其采摘过程传统上依赖于人工劳作…...

自动控制原理——BliBli站_DR_CAN

自动控制 2 稳定性分析 极点在左半平面 输入为单位冲击&#xff0c;而拉普拉斯变换为1&#xff1b;因此&#xff0c;开环和闭环系统&#xff0c;研究其传递函数的稳定性就可以了 2.5_非零初始条件下的传递函数_含有初始条件的传递函数 如果一个系统的初始条件不为0&#xff0…...

使用phpStudy小皮面板模拟后端服务器,搭建H5网站运行生产环境

一.下载安装小皮 小皮面板官网下载网址&#xff1a;小皮面板(phpstudy) - 让天下没有难配的服务器环境&#xff01; 安装说明&#xff08;特别注意&#xff09; 1. 安装路径不能包含“中文”或者“空格”&#xff0c;否则会报错&#xff08;例如错误提示&#xff1a;Cant cha…...

vue2 pinia 安装与入门

安装 本体 npm install pinia vue2特定 npm install vue/composition-api 持久化存本地 npm install pinia-plugin-persistvue.config.js 不加的话会报错 configureWebpack: { // 在configureWebpack里加上以下modulemodule: {rules: [{test: /\.mjs$/,include: /node_mo…...

路由传参、搜索、多选框勾选、新增/编辑表单复用

前言&#xff1a; 记录添加运动员页面功能的具体实现 ①由赛事管理页面跳转时路由传参&#xff08;携带该页面表格中莫某条数据对应的赛事id到另一个页面&#xff09;&#xff1b; ②搜索框实时搜索&#xff1b; ③多选框勾选搜索&#xff1b; ④新增表单和编辑表单复用&a…...

内网不出网上线cs

一:本地正向代理目标 如下&#xff0c;本地(10.211.55.2)挂好了基于 reGeorg 的 http 正向代理。代理为: Socks5 10.211.55.2 1080python2 reGeorgSocksProxy.py -l 0.0.0.0 -p 1080 -u http://10.211.55.3:8080/shiro/tunnel.jsp 二&#xff1a;虚拟机配置proxifer 我们是…...