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

80386 ATT汇编语法

文章目录

  • gcc的预处理,不进行编译、汇编或链接
    • 预处理
    • 编译
    • 汇编
  • 8.8.2 AT&T语法与英特尔语法
  • 8.8.3操作码命名
  • 8.8.4寄存器命名
  • 8.8.5操作码前缀
  • 8.8.6内存引用
  • 8.8.7跳转指令的处理
  • 8.8.8浮点
  • 8.8.9写入16位代码
  • 8.8.10笔记

gcc的预处理,不进行编译、汇编或链接

gcc选项-E                       仅作预处理,不进行编译、汇编或链接。-S                       编译到汇编语言,不进行汇编和链接,-c                       编译、汇编到目标代码,不进行链接。-o <文件>                输出到 <文件>-pie                     生成动态链接的位置无关可执行文件。-shared                  生成一个共享库。-x <语言>                指定其后输入文件的语言。允许的语言包括:c、c++、assembler、none‘none’意味着恢复默认行为,即根据文件的扩展名猜测源文件的语言。
[hao@bogon qemu-demo]$ gcc -v -c test.S -o test.o
使用内建 specs。
COLLECT_GCC=gcc
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
目标:x86_64-redhat-linux
配置为:../configure --enable-bootstrap --enable-host-pie --enable-host-bind-now --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-plugin --enable-initfini-array --without-isl --enable-multilib --with-linker-hash-style=gnu --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_64=x86-64-v2 --with-arch_32=x86-64 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1
线程模型:posix
Supported LTO compression algorithms: zlib zstd
gcc 版本 11.4.1 20231218 (Red Hat 11.4.1-3) (GCC)
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'test.o' '-mtune=generic' '-march=x86-64-v2'/usr/libexec/gcc/x86_64-redhat-linux/11/cc1 -E -lang-asm -quiet -v test.S -mtune=generic -march=x86-64-v2 -fno-directives-only -o /tmp/ccZppfRe.s
忽略不存在的目录“/usr/lib/gcc/x86_64-redhat-linux/11/include-fixed”
忽略不存在的目录“/usr/lib/gcc/x86_64-redhat-linux/11/../../../../x86_64-redhat-linux/include”
#include "..." 搜索从这里开始:
#include <...> 搜索从这里开始:/usr/lib/gcc/x86_64-redhat-linux/11/include/usr/local/include/usr/include
搜索列表结束。
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'test.o' '-mtune=generic' '-march=x86-64-v2'as -v --64 -o test.o /tmp/ccZppfRe.s
GNU assembler version 2.35.2 (x86_64-redhat-linux) using BFD version version 2.35.2-43.el9
COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/11/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/11/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/11/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'test.o' '-mtune=generic' '-march=x86-64-v2' '-dumpdir' 'test.'

预处理

gcc -E test.c -o test.S

将头文件内容包含到源文件中。生成test.S文件。

编译

gcc -E test.S -o /tmp/ccZppfRe.s

将预处理文件编译成汇编语言文件。

汇编

as --64 -o test.o /tmp/ccZppfRe.s

将汇编语言文件编译成目标文件。

8.8.2 AT&T语法与英特尔语法

AT&T 汇编语法,通常称为 GAS 语法(GNU as汇编器的语法)。保持与gcc的输出的兼容性

为了保持与gcc的输出的兼容性,as支持AT&T System V/386汇编程序语法。这与英特尔的语法大不相同。我们之所以提到这些差异,是因为几乎所有80386文档都只使用了Intel语法。这两种语法之间的显著区别在于:

  • AT&T立即数操作数前面是“$”;英特尔立即数操作数不受限制(英特尔的“push 4”是AT&T的“pushl $4”)。
    AT&T寄存器操作数前面有“%”;英特尔寄存器操作数不受限制。
    AT&T绝对(与PC相对)跳转/调用操作数的前缀为“*”;它们在英特尔语法中是不受限制的。
操作AT&TINTEL
立即数操作pushl $4push 4
寄存器操作pushl %axpush ax
绝对跳转/调用操作jmp *0x100;call *0x100jmp 0x100; call 0x100
  • AT&T和Intel语法对源操作数和目标操作数使用相反的顺序。英特尔的“add eax,4”就是“addl $4,%eax”。为了与以前的Unix汇编程序兼容,保留了“source,dest”约定。
操作AT&TINTEL
源操作数和目标操作数addl $4,%eaxadd eax,4
【source, dest】【dest, source】

将4放入寄存器eax中。

  • 在AT&T语法中,内存操作数的大小由操作码名称的最后一个字符决定。操作码后缀’b’、'w’和’l’指定字节(8位)、字(16位)和长(32位)内存引用。英特尔语法通过在内存操作数(而不是操作码本身)前面加上“byte ptr”、“word ptr”和“dword ptr”来实现这一点。因此,英特尔的“mov al,byte ptr foo”在AT&T语法中是“movb foo,%al”。
操作AT&TINTEL
内存操作数的大小movb foo,%almov al,byte ptr foo

将一个字节大小类型的foo变量放入al寄存器中。

  • 立即形式的长跳转和调用在AT&T语法中是“lcall/ljmp $section, $offset”;英特尔的语法是“call/jmp far section:offset”。此外,远返回指令是AT&T语法中的“lret $stack adjust”;英特尔的语法是“ret far stack-adjust”。
  • AT&T汇编程序不支持多节(section)程序。Unix风格的系统期望所有程序都是单个sections。
操作AT&TINTEL
立即形式的长跳转和调用lcall/ljmp $section, $offsetcall/jmp far section:offset
远返回指令lret $stack adjustret far stack-adjust

8.8.3操作码命名

操作码名称后缀为一个字符修饰符,用于指定操作数的大小。字母“b”、“w”和“l”指定字节、单词和长操作数。如果指令没有指定后缀,并且它不包含内存操作数,则as会尝试根据目标寄存器操作数(约定为最后一个)填充缺少的后缀。因此,“mov%ax,%bx”等效于“movw%ax,%bx”;此外,“movw$1,%bx”等效于“movvw$1,%bx”。请注意,这与AT&T Unix汇编程序不兼容,后者认为缺少操作码后缀意味着操作数大小较长。(这种不兼容性不会影响编译器输出,因为编译器总是显式指定操作码后缀。)
在AT&T和Intel格式中,几乎所有操作码都有相同的名称。也有一些例外。符号扩展和零扩展指令需要两种大小来指定它们。它们需要一个大小来进行签名/zero-extend-from和一个大小to zero-extend to。这是通过在AT&T语法中使用两个操作码后缀来实现的。符号扩展和零扩展的基本名称是“movs…”和“movz…”在AT&T语法中(英特尔语法中的’vsx’和’movzx’)。这个操作码后缀被附加到这个基本名称上,从后缀在到后缀之前。因此,“movsbl%al,%edx”是AT&T的语法,表示“移动符号从%al扩展到%edx。”因此,可能的后缀有“bl”(从字节到长)、“bw”(从不字节到单词)和“wl”(从单词到长)。
英特尔语法转换指令
•“cbw”–将“%l”中的字节符号扩展到“%ax”中的字,
•“cwde”–将“%ax”中的扩展字符号化为“%eax”中的long,
•“cwd”–对“%ax”中的单词进行符号扩展,使其在“%dx:%ax”中变长,
•“cdq”–将“%eax”中的双字符号扩展到“%edx:%eax”的quad,
在AT&T命名中称为“cbtw”、“cwtl”、“cwtd”和“cltd”。as接受这些指令的任一命名。
远调用/跳转指令在AT&T语法中为“lcall”和“ljmp”,但在Intel约定中为“call Far”和“jump Far”。

8.8.4寄存器命名

寄存器操作数总是以“%”为前缀。80386寄存器包括

  • 8个32位寄存器“%eax”(累加器)、“%ebx”、“%ecx”、”%edx“、”%ddi“、”%esi“、”%ebp“(帧指针)和”%esp“(堆栈指针)。
  • 它们的8个16位低端:“%ax”、“%bx”、“%cx”、”%dx“、”%di“、”%si“、“%bp”和”%sp“。
  • 8个8位寄存器:“%ah”、“%al”、“%bh”、“%l”、”%ch“、”%cl“、”%dh“和”%dl“(这些是”%ax“、”%bx“、”%cx“和”%dx“的高字节和低字节)
  • 6段寄存器“%cs”(代码段)、“%ds”(数据段)、”%ss“(堆栈段)、‘%s’、”%fs“和”%gs“。
  • 3个处理器控制寄存器“%cr0”、“%cr2”和“%cr3”。
  • 6个调试寄存器“%db0”、“%db1”、“%db2”、“%db3”、“%tb6”和“%db7”。
  • 2个测试寄存器“%tr6”和“%tr7”。
  • 8浮点寄存器堆栈“%st”,或等效的‘%st(0)’, ‘%st(1)’, ‘%st(2)’,‘%st(3)’, ‘%st(4)’, ‘%st(5)’, ‘%st(6)’, and ‘%st(7)’.。

8.8.5操作码前缀

操作码前缀用于修改以下操作码。它们用于重复字符串指令、提供节(section)重写、执行总线锁定操作以及指定操作数和地址大小(在指令中,通过在通常为32位操作数的操作数前面加上“操作数大小”操作码前缀来指定16位操作数)。操作码前缀通常作为没有操作数的单行指令给出,并且必须直接位于它们所执行的指令之前。例如,“scas”(扫描字符串:scan string)指令重复使用:

	repne scas

以下是操作码前缀列表:

  • 节重写前缀为“cs”、“ds”、“ss”、“es”、“fs”、“gs”。通过为内存引用指定section:memory-operand形式,可以自动添加这些值。
  • 操作数/地址大小前缀“data16”和“addr16”将32位操作数/寻址更改为16位操作数或寻址。请注意,目前还不支持16位寻址模式(即8086和80286寻址模式)。
  • 总线锁定前缀“lock”在执行其前面的指令期间禁止中断。(这仅在特定说明下有效;有关详细信息,请参阅80386手册)。
  • 等待协处理器前缀“wait”等待协处理器完成当前指令。80386/80387组合不应该需要此功能。
  • “rep”、“repe”和“repne”前缀被添加到字符串指令中,使它们重复“%ecx”次。

8.8.6内存引用

Intel语法间接内存引用的形式

section:[base + index*scale + disp]

被翻译成AT&T语法

section:disp(base, index, scale)

其中,base和index是可选的32位base寄存器和index寄存器,disp是可选的位移,scale取值1、2、4和8,乘以索引(index)以计算操作数的地址。如果未指定比例(scale),则比例(scale)为1。节(section)指定内存操作数的可选section寄存器,并且可以覆盖默认的section寄存器(有关section寄存器默认值,请参阅80386手册)。请注意,AT&T语法中的节(section)重写前面必须有一个“%”。如果指定与默认section寄存器一致的section重写,则不会输出任何section寄存器重写前缀来汇编给定指令。因此,可以指定区段重写来强调哪个区段寄存器用于给定的内存操作数。

以下是英特尔和AT&T风格内存参考的一些示例:

AT&T: '-4(%ebp)', Intel: '[ebp - 4]'

base为“%ebp”;disp为“-4”。缺少section,使用了默认section(“%ss”用于以“%ebp”作为base寄存器进行寻址)。index和scale都不见了。

AT&T: 'foo(,%eax,4)', Intel: '[foo + eax*4]'

index为“%eax”(按scale 4缩放);disp是“foo”。缺少所有其他字段。此处的section寄存器默认为“%d”。

AT&T: 'foo(,1)'; Intel '[foo]'

这将使用“foo”指向的值作为内存操作数。请注意,base和index都丢失了,但只有一个“,”。这是一个句法上的例外。

AT&T: '%gs:foo'; Intel 'gs:foo'

这将选择变量“foo”的内容,其中section寄存器section为“%gs”。

绝对(与PC相对)调用和跳转操作数必须以“”为前缀。
如果未指定“
”,则一如既往地为跳转/调用标签选择PC相对寻址。
任何具有内存操作数的指令都必须使用操作码后缀(分别为’b’、‘w’或’l’)指定其大小(字节、字或长)。

8.8.7跳转指令的处理

跳转指令总是经过优化,以使用尽可能小的位移。这是通过每当目标足够接近时使用字节(8位)位移跳跃来实现的。如果字节位移不足,则使用长(32位)位移。我们不支持字(16位)位移跳跃(即在跳跃指令前加上“addr16”操作码前缀),因为80386坚持在添加字位移后将“%eip”屏蔽为16位。
请注意,‘jcxz’、‘jecxz’、‘sloop’、‘loopz’、‘aloope’、'loopnz’和’loopne’指令仅以字节位移形式出现,因此,如果使用这些指令(gcc不使用它们),则可能会收到错误消息(和不正确的代码)。AT&T 80386汇编程序试图通过将“jcxz-foo”扩展到

		jcxz cx_zero jmp cx_nonzero
cx_zero:jmp foo 
cx_nonzero:

8.8.8浮点

支持除压缩BCD之外的所有80387浮点类型。(添加BCD支持可能没有太大困难)。这些数据类型是16位、32位和64位整数,以及单(32位)、双(64位)和扩展(80位)精度浮点。每个支持的类型都有一个操作码后缀和一个与之相关的构造函数。操作码后缀指定操作数的数据类型。构造函数将这些数据类型构建到内存中。
•浮点构造函数是32位、64位和80位格式的“.foat”或“.ssingle”、“.double”和“.tfloat”。这些对应于操作码后缀“s”、“l”和“t”t’代表临时实数,80387仅通过’fldt’(将临时实数加载到堆栈顶部)和’fstpt’(存储临时实数和弹出堆栈)指令支持此格式。
•对于16位、32位和64位整数格式,整数构造函数为“.word”、“.long”或“.int”以及“.fquad”。相应的操作码后缀是’s’(single)、‘l’(long)和’q’(quad)。与临时实数格式一样,64位“q”格式仅存在于“fildq”(将四进制整数加载到堆栈顶部)和“fistpq”(存储四进制整数和弹出堆栈)指令中。
注册到注册操作不需要操作码后缀,因此“fst%st,%st(1)”等效于“fstl %st,%s1(1))”。

8.8.9写入16位代码

虽然GAS通常只编写“纯”32位i386代码,但它对编写在真实模式或16位保护模式代码段中运行的代码的支持有限。为此,在要以16位模式运行的汇编语言指令之前插入“.code16”指令。您可以使用“.code32”指令将GAS切换回编写正常的32位代码。
GAS在16位模式下理解的汇编语言语法与在32位模式下完全相同。任何给定指令的函数在任何模式下都是完全相同的,只要生成的目标代码是在GAS编写它的模式下执行的。因此,例如,“ret”助记符生成32位返回指令,无论它是在16位模式还是32位模式下运行。(如果GAS处于16位模式,它将向指令添加一个操作数大小前缀,以强制其返回32位。)

这意味着,首先,您可以使用gnucc编写要在真实模式或16位保护模式下运行的代码。只需插入语句“asm(“.code16”);”在C源文件的开头,虽然gnu-cc仍将生成32位代码,但GAS将自动添加所有必要的大小前缀,使代码以16位模式运行。当然,由于gnu-cc只写小的模型代码(它不知道如何像原生x86编译器那样将段选择器附加到指针上),所以使用gnu-cc编写的任何16位代码基本上都将限制在64K的地址空间内。此外,由于GAS必须向指令中添加所有额外的地址和操作数大小前缀,因此会导致代码大小和性能损失。

请注意,将GAS置于16位模式并不意味着生成的代码必须在80386之前的16位处理器上运行。要编写在这样的处理器上运行的代码,您必须避免使用任何需要GAS输出地址或操作数大小前缀的32位结构。目前,这将相当困难,因为GAS目前只支持32位寻址模式:当写入16位代码时,它总是为任何使用非寄存器寻址模式的指令输出地址大小前缀。因此,您可以编写在16位处理器上运行的代码,但前提是该代码从不引用内存。

8.8.10笔记

有一些关于“mul”和“imul”指令的诡计值得一提。16位、32位和64位扩展乘法(基本操作码“0xf6”;“mul”的扩展码4和“imul”的扩展名5)只能以一个操作数形式输出。因此,“imul%ebx,%eax”不选择扩展乘法;扩展乘法会阻塞“%dx”寄存器,这会混淆gcc的输出。使用“imul%ebx”获取“%edx:%eax”中的64位乘积。

当第一个操作数是立即数模式表达式,第二个操作数为寄存器时,我们添加了一个双操作数形式的“imul”。这只是一个简写,因此,例如,将“%eax”乘以69,可以使用imul $69,%eax,而不是“imul $69,%eax,%eax’”。

相关文章:

80386 ATT汇编语法

文章目录 gcc的预处理&#xff0c;不进行编译、汇编或链接预处理编译汇编 8.8.2 AT&T语法与英特尔语法8.8.3操作码命名8.8.4寄存器命名8.8.5操作码前缀8.8.6内存引用8.8.7跳转指令的处理8.8.8浮点8.8.9写入16位代码8.8.10笔记 gcc的预处理&#xff0c;不进行编译、汇编或链…...

如何在Linux系统使用宝塔面板搭建Inis博客并发布至公网【内网穿透】

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…...

【漏洞复现】netgear路由器 boarddataww 存在RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…...

什么是原型链

1、原型链的本质 是一个链表&#xff0c;当使用一个构造函数时&#xff0c;就会返回一个实例&#xff0c;在这个实例上找某个属性未找到时&#xff0c;则会顺着proto属性指向它的原型&#xff0c;去原型上找&#xff0c;如果原型也没有的话&#xff0c;则会顺着原型的原型找&a…...

什么是虚拟线程?

1、典型回答 Java 中的虚拟线程&#xff0c;也叫做协程或“轻量级线程”&#xff0c;它诞生于JDK 19(预览 API)&#xff0c;正式发布于 JDK 21&#xff0c;它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程&#xff0c;不直接和操作系统的物理线程一一对应&#xff0c;因此它可…...

node.js是什么怎么用常用方法

什么是node.js Node.js是一个基于Chrome V8 JavaScript引擎的服务器端运行环境。它允许使用JavaScript来开发高性能的网络应用程序。Node.js采用事件驱动、非阻塞式I/O模型&#xff0c;使其能够处理大量并发请求而不会出现阻塞。 Node.js最初是由Ryan Dahl于2009年创建的&…...

pikachu靶场第十四关——XSS(跨站脚本)之js输出(附代码审计)

源代码&#xff1a; //这里讲输入动态的生成到了js中,形成xss //javascript里面是不会对tag和字符实体进行解释的,所以需要进行js转义//讲这个例子主要是为了让你明白,输出点在js中的xss问题,应该怎么修? //这里如果进行html的实体编码,虽然可以解决XSS的问题,但是实体编码后…...

AD实用设置教程

目录 一、“多边形敷铜” 设置 “最小间隔” 二、放置的 “过孔” 敷铜 “全连接”...

webpack为什么要使用loader,如何手写loader

webpack是一个打包工具&#xff0c;即webpack会将一切文件视为模块&#xff0c;但是webpack在打包的时候只是认识JS文件或者JSON文件&#xff0c;并不认识CSS文件&#xff0c;png图片等&#xff0c;如果想让webpack能够在打包的时候识别其他文件&#xff0c;就必须要使用loader…...

【银河商学】大蓝短视频学习04——找对标账号

为什么要找对标账号&#xff1f; 标准答案&#xff0c;少走弯路秒上热搜&#xff0c;快速起号预知变现&#xff0c;扬长避短 找什么样的对标账号&#xff1f; 成熟 粉丝量 > 50万持续更新&#xff0c;多年屹立不倒 举例账号 三百者也 模仿 二百者也 易做 简单可量产 有潜…...

Java练手游戏--俄罗斯方块

Java基础小练手游戏项目&#xff1a;俄罗斯方块简单版 使用Java实现俄罗斯方块大概思路&#xff1a; 界面设计&#xff1a; 使用Java Swing或JavaFX创建游戏窗口和用户界面。创建一个主窗口类&#xff08;如GameFrame.java&#xff09;&#xff0c;负责设置窗口大小、标题等属…...

基础篇Redis

基础篇Redis 1.Redis简单介绍 Redis是一种键值型的NoSql数据库&#xff0c;这里有两个关键字&#xff1a; 键值型NoSql 其中键值型&#xff0c;是指Redis中存储的数据都是以key.value对的形式存储&#xff0c;而value的形式多种多样&#xff0c;可以是字符串.数值.甚至json…...

透视变换详解

透视变换&#xff08;Perspective Transformation&#xff09;是一种用于在图像处理中对图像进行几何变换的技术&#xff0c;它可以用来校正图像的透视形变或者改变图像的视角。透视变换通常涉及到一个原始图像和一个目标图像之间的转换&#xff0c;其中原始图像可能是一个投影…...

leetcode LCR121.寻找目标值-二维数组

目录 问题描述示例具体思路思路一思路二 代码实现 问题描述 m*n 的二维数组 plants 记录了园林景观的植物排布情况&#xff0c;具有以下特性&#xff1a; 每行中&#xff0c;每棵植物的右侧相邻植物不矮于该植物&#xff1b; 每列中&#xff0c;每棵植物的下侧相邻植物不矮于该…...

成都百洲文化传媒有限公司引领电商服务新潮流

在当今数字化时代&#xff0c;电商行业日新月异&#xff0c;竞争激烈。然而&#xff0c;在这个浪潮中&#xff0c;成都百洲文化传媒有限公司凭借其专业的电商服务&#xff0c;脱颖而出&#xff0c;成为了行业中的新领军者。今天&#xff0c;我们就来探讨一下这家公司如何在这个…...

【C++从练气到飞升】05---运算符重载

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 ⛳️推荐 一、运算符重载的引用 二、运算符重载 三、赋值运算符重载 1 .赋值运算符重载格式: 2 .赋值运算符只能重载成…...

[leetcode] 994. 腐烂的橘子

在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单元格中没有…...

如何本地搭建群晖虚拟机并实现无quickconnect服务环境远程访问

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…...

[Java基础揉碎]final关键字

目录 介绍 在某些情况下&#xff0c;程序员可能有以下需求&#xff0c;就会使用到final final注意事项和讨论细节 1) final修饰的属性又叫常量&#xff0c;一般用XX_XX_XX来命名 2) final修饰的属性在定义时&#xff0c;必须赋初值&#xff0c;并且以后不能再修改&#…...

用OceanBase binlog service 轻松进行数据回滚

背景 在日常的数据库运维过程中&#xff0c;难免会遭遇数据误操作的情形&#xff0c;比如因疏忽而执行了非预期的delete或update操作&#xff0c;这时就需要进行数据回滚。如果在OceanBase中启用了回收站功能&#xff0c;并设置了合适的undo_retention&#xff0c;那么我们可以…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...