Bochs源码分析 - 24:bochs对Non-PAE-4K页的实现代码

Bochs源码分析 - 11:《X86探索及编程》代码初步解释 前言 现在我们来阅读邓志老师的《x86/x64体系探索及编程》,边阅读边将其代码放到bochs中运行,然后观察bochs的CPU是如何来模拟的。现在我们来详细分析ex3-2目录里面的内容。 boot.asm 代码解读 自己在工作中经常看汇编代码,但是写汇编代码真的很少写过,我们现在一边分析着这段boot汇编代码一边回顾其如何编写。 ; Int 19h 加载 sector 0 (MBR) 进入 BOOT_SEG 段, BOOT_SEG 定义为 0x7c00 ... 阅读详情

前言

        我们现在在构建好分页模式的基础上,来通过对mov指令的分析来实现对bochs的Non-PAE-4K分页机制的分析,在分析过程中,我们会看到关于对页属性的各种检查,之后再来总结。

        注意,其中可能涉及缓存部分(TLB),这个我们决定放在后面分析,因此如果遇到TLB信息,我们暂且跳过,不做过多解读。

反汇编定位代码

        我们现在先将ex11-2/protected.asm中测试二的代码注释掉,为分析直观,将mov[xx],0 改为 mov[xx],4. 然后按照我们上篇文章补充的Shell脚本来进行编译,内容如下:

; 测试二:在 CR0.WP=0时,在0级代码里写0x400000地址
       mov DWORD [0x400000], 4   

        使用IDA来逆向这部分,定位其汇编地址,内容如下:

        现在通过bochs来运行到bochs反汇编代码,内容如下:

堆栈分析-1

        其核心代码在 BX_CPU_C::access_write_linear(...) 中,从cpu->execute1(...)到access_write_linear(...) 经过一系列函数,这些函数并没有什么核心代码,只是基本单纯地封装调用,我们直接展示其函数堆栈。

>	bochs.exe!BX_CPU_C::access_write_linear(unsigned __int64 laddr, unsigned int len, unsigned int curr_pl, unsigned int xlate_rw, unsigned int ac_mask, void * data) Line 2402	C++
 	bochs.exe!BX_CPU_C::write_linear_dword(unsigned int s, unsigned __int64 laddr, unsigned int data) Line 102	C++
 	bochs.exe!BX_CPU_C::write_virtual_dword(unsigned int s, unsigned __int64 offset, unsigned int data) Line 200	C++
 	bochs.exe!BX_CPU_C::MOV_EdIdM(bxInstruction_c * i) Line 30	C++
 	bochs.exe!BX_CPU_C::cpu_loop() Line 109	C++

access_write_linear(...)函数分析

        我们现在来分析access_write_linear(..)的代码,其函数定义如下:

int BX_CPU_C::access_write_linear(
    bx_address laddr, // 线性地址 0x400000
    unsigned len,     // 数据长度 4
    unsigned curr_pl, // 当前的CPL 0
    unsigned xlate_rw, // 读写  BX_WRITE
    Bit32u ac_mask,     // 0x3
    void *data // 写入数据的指针
){
    ....
}

        在这部分函数中,有两个非常重要的代码,下面我们会重点分析这两部分代码。

        translate_linear(...)函数是将线性地址转化为物理地址,其中有一个tlbEntry,这个是TLB页缓的,如果该地址在tlb中存在缓存,则优先从缓存中获取。

    bx_bool user = (curr_pl == 3);
    BX_CPU_THIS_PTR address_xlation.paddress1 = 
        translate_linear(tlbEntry, laddr, user, xlate_rw);

        下面这个是写入数据,此时已经拿到物理地址了,将该函数写入地址。

access_write_physical(
    BX_CPU_THIS_PTR address_xlation.paddress1, len, data);

translate_linear(...)函数分析

        这部分代码如下,先来检查当前权限,我们此时仅是写,这里计算出lpf,这个就是线性地址取整数,通过这个值在tlb缓存中查询(暂时不分析),如果可以查询到,直接从tlb查询到对应的物理地址,直接返回。

  unsigned isWrite = rw & 1; // write or r-m-w
  unsigned isExecute = (rw == BX_EXECUTE);
  unsigned isShadowStack = (rw & 4); // 4 if shadowstack and 0 otherwise
  bx_address lpf = LPFOf(laddr); // return laddr & 0xfffffffffffff000; 

    // 从缓存中查询
  if (! isExecute && TLB_LPFOf(tlbEntry->lpf) == lpf){
    ...

  }

        下面这段代码就是判断寻址模式的代码,很好理解,其先来检查cr0寄存器代码是否开启,然后检查是否开启Long_mode模式,如果开启直接选择4-level分页模式解析,否则再来判断是否开启PAE,其对应选择PAE与NonPAE两种分页模式。

        我们这里肯定是调用translate_linear_legacy(...),这里legacy是"传统"的含义,对应的就是我们所讲的Non-Page分页模式,我们继续来分析这个函数。

if(BX_CPU_THIS_PTR cr0.get_PG())
  {
    BX_DEBUG(("page walk for%s address 0x" FMT_LIN_ADDRX, isShadowStack ? " shadow stack" : "", laddr));

#if BX_CPU_LEVEL >= 6
#if BX_SUPPORT_X86_64
    if (long_mode())
      paddress = translate_linear_long_mode(laddr, lpf_mask, pkey, user, rw);
    else
#endif
      if (BX_CPU_THIS_PTR cr4.get_PAE())
        paddress = translate_linear_PAE(laddr, lpf_mask, user, rw);
      else
#endif 
        paddress = translate_linear_legacy(laddr, lpf_mask, user, rw);
#endif
  }  else {
    // no paging
    paddress = (bx_phy_address) laddr;
    combined_access |= (BX_MEMTYPE_WB << 9); // act as memory type by paging is WB
  }

 translate_linear_legacy(...)函数分析

        该函数表示来解析NonPage分页模式获取物理页,下面是这部分的核心代码,之后我们会围绕这部分代码来进行分析。

bx_phy_address BX_CPU_C::translate_linear_legacy(bx_address laddr, Bit32u &lpf_mask, unsigned user, unsigned rw)
{    
  bx_phy_address entry_addr[2], ppf = (Bit32u) BX_CPU_THIS_PTR cr3 & BX_CR3_PAGING_MASK;
  Bit32u entry[2];
  BxMemtype entry_memtype[2] = { 0 };
  int leaf;

  lpf_mask = 0xfff;
  Bit32u combined_access = (BX_COMBINED_ACCESS_WRITE | BX_COMBINED_ACCESS_USER);
  Bit32u curr_entry = (Bit32u) BX_CPU_THIS_PTR cr3;

  for (leaf = BX_LEVEL_PDE;; --leaf) {
    entry_addr[leaf] = ppf + ((laddr >> (10 + 10*leaf)) & 0xffc);

    }

    access_read_physical(entry_addr[leaf], 4, &entry[leaf]);

    curr_entry = entry[leaf];
    if (!(curr_entry & 0x1)) {
      BX_DEBUG(("%s: entry not present", bx_paging_level[leaf]));
      page_fault(ERROR_NOT_PRESENT, laddr, user, rw);
    }

    ppf = curr_entry & 0xfffff000;

    if (leaf == BX_LEVEL_PTE) break;

#if BX_CPU_LEVEL >= 5
    if ((curr_entry & 0x80) != 0 && BX_CPU_THIS_PTR cr4.get_PSE()) {
      // 4M paging, only if CR4.PSE enabled, ignore PDE.PS otherwise
      if (curr_entry & PAGING_PDE4M_RESERVED_BITS) {
        BX_DEBUG(("PSE PDE4M: reserved bit is set: PDE=0x%08x", entry[BX_LEVEL_PDE]));
        page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, user, rw);
      }

      // make up the physical frame number
      ppf = (curr_entry & 0xffc00000);
#if BX_PHY_ADDRESS_WIDTH > 32
      ppf |= ((bx_phy_address)(curr_entry & 0x003fe000)) << 19;
#endif
      lpf_mask = 0x3fffff;
      break;
    }
#endif

    combined_access &= curr_entry; // U/S and R/W
  }
    ...
    ...
}

         首先,其先通过cpu.cr3来获取pde页表的基址 0x100000,代码如下,我们也展示出在汇编中的相关代码。

ppf = (Bit32u) BX_CPU_THIS_PTR cr3 & BX_CR3_PAGING_MASK;


;*** 32-bit paging �� ***
%define PDT32_BASE              100000h
mov eax, PDT32_BASE
mov cr3, eax

         之后来构建变量combined_access,这里这么写的原因是页权限读写是由多级页表项所共同决定的,因此我们先预设个最大值,之后每读一个页表项,则来进行一个&运算,最后可以得到该页的最终访问值。

Bit32u combined_access = (BX_COMBINED_ACCESS_WRITE | BX_COMBINED_ACCESS_USER);

        下面来到核心循环部分,注意该结构体,并没有终止条件,因此其退出是break(该循环中没有false),我们是Non-Page,因此从PDE开始递归搜索,leaf = BX_LEVEL_PDE。

enum {
  BX_LEVEL_PML4 = 3,
  BX_LEVEL_PDPTE = 2,
  BX_LEVEL_PDE = 1,
  BX_LEVEL_PTE = 0
};

for (leaf = BX_LEVEL_PDE;; --leaf) { 
    ... 
}

         下面这部分很好理解,就是来计算地址偏移,注意其 (laddr >> 20) & 0xffc,相当于 (laddr >> 22) * 4,因为在PDT中项的长度为4个字节,这样entry_addr[1]中存储着PDE项了。

entry_addr[leaf] = ppf + ((laddr >> (10 + 10*leaf)) & 0xffc);

// 之前用c++模拟的代码
*offset_1 = (address >> 22);

        然后调用access_read_physical(...)这个函数来获取PTT的地址,放在entry[1]中。

access_read_physical(entry_addr[leaf], 4, &entry[leaf]);

       拿到该页之后其判断p位是否有效,然后判断当前是否在BX_LEVEL_PTE,如果是则说明解析完成,否则退出。当然我们现在还在BX_LEVEL_PDE,还要继续往下分析。

    curr_entry = entry[leaf];
    if (!(curr_entry & 0x1)) {
      BX_DEBUG(("%s: entry not present", bx_paging_level[leaf]));
      page_fault(ERROR_NOT_PRESENT, laddr, user, rw);
    }

    ppf = curr_entry & 0xfffff000;

    if (leaf == BX_LEVEL_PTE) break;

        下面这个就是来判断是否是大页PS(4M)模式了,其除了判断PDE项,还要来判断CR4.PSE位来查看CPU是否开启这个模式。如果是大页模式这直接获取对应的地址,然后break掉不往下继续解析。我们这是4K模式,因此继续往下解析。

    if ((curr_entry & 0x80) != 0 && BX_CPU_THIS_PTR cr4.get_PSE()) {
      // 4M paging, only if CR4.PSE enabled, ignore PDE.PS otherwise
      if (curr_entry & PAGING_PDE4M_RESERVED_BITS) {
        BX_DEBUG(("PSE PDE4M: reserved bit is set: PDE=0x%08x", entry[BX_LEVEL_PDE]));
        page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, user, rw);
      }

      // make up the physical frame number
      ppf = (curr_entry & 0xffc00000);
#if BX_PHY_ADDRESS_WIDTH > 32
      ppf |= ((bx_phy_address)(curr_entry & 0x003fe000)) << 19;
#endif
      lpf_mask = 0x3fffff;
      break;
    }

        下面这个就是来更新当前项的访问模式,使用&运算符,内容如下:

combined_access &= curr_entry; // U/S and R/W

        之后开启第二次循环,leaf--,达到BX_LEVEL_PTE模式,再来经历一轮读取内存等操作,最后遇到下面这条语句来结束循环,之后来进行返回。


    ppf = curr_entry & 0xfffff000;

    if (leaf == BX_LEVEL_PTE) break;

        我们返回的就是pff这个|combined_access,我们所需要的线性地址对应的物理地址以及读写权限。这段代码后半部分是各种权限检查,我们先绕过去,不继续分析了。

return (ppf | combined_access);

access_write_physical(...)函数分析

        该函数调用堆栈如下,这部分代码没有什么好分析的,就是单纯的函数调用。

>	bochs.exe!WriteHostDWordToLittleEndian(unsigned int * hostPtr, unsigned int nativeVar32) Line 545	C++
 	bochs.exe!BX_MEM_C::writePhysicalPage(BX_CPU_C * cpu, unsigned __int64 addr, unsigned int len, void * data) Line 99	C++
 	bochs.exe!BX_CPU_C::access_write_physical(unsigned __int64 paddr, unsigned int len, void * data) Line 2599	C++
 	bochs.exe!BX_CPU_C::access_write_linear(unsigned __int64 laddr, unsigned int len, unsigned int curr_pl, unsigned int xlate_rw, unsigned int ac_mask, void * data) Line 2410	C++

        值得注意的是下面代码,在WritePhysicalPage中,传递的指针通过 get_vector(a20addr)这个函数返回得到,可以看出其物理页面存储在 mm.blocks[block]结构体中,然后通过 (Bit32u)(addr & (BX_MEM_BLOCK_LEN-1)) 来获取对应的偏移。

        Mem & (0x1000 -1) 这种算法表示获取Mem后面0x1000的内容,这种写法要明确。

        这里的mm.blocks[..]我们在前面bochs初始化章节有过讲解,可以回去翻阅相关内容。

WriteHostDWordToLittleEndian((Bit32u*) BX_MEM_THIS get_vector(a20addr), *(Bit32u*)data);


BX_CPP_INLINE Bit8u* BX_MEM_C::get_vector(bx_phy_address addr)
{
  Bit32u block = (Bit32u)(addr / BX_MEM_BLOCK_LEN);
#if (BX_LARGE_RAMFILE)
  if (!BX_MEM_THIS blocks[block] || (BX_MEM_THIS blocks[block] == BX_MEM_THIS swapped_out))
#else
  if (!BX_MEM_THIS blocks[block])
#endif
    allocate_block(block);

  return BX_MEM_THIS blocks[block] + (Bit32u)(addr & (BX_MEM_BLOCK_LEN-1));
}

        最后,这就是将数据写入进去

BX_CPP_INLINE void WriteHostDWordToLittleEndian(Bit32u *hostPtr, Bit32u nativeVar32)
{
  *(hostPtr) = nativeVar32;
}

总结

        分析完bochs对这边代码的实现,现在这里只是分析了一个大体流程,我们可以看到三种分页模式的解析,之后我们会着重来分析有关属性权限检查。

比较重要的几个函数

access_write_physical - 写入物理页

translate_linear - 线性地址转换为物理地址

translate_linear_long_mode - LongMode模式页解析

translate_linear_PAE - PAE模式解析

translate_linear_legacy - Non-PAE模式解析

        下面是我们在源码中分析得到的一种取值技巧,其OFFSET来定义来获取后面多少位,我们这里是12,表示获取后面12位,最后输出结果 0x234。 这种技巧我们之前也经常遇到过,但是可能当时无心或者技术不行,根本学不会,现在来看真的很巧妙。

#define OFFSET 12
int main(int argc, char const* argv[]) {

	int laddr = 0x1234;
	int offset = 0x1234 & ((1 << OFFSET) - 1);
	cout << hex << offset << endl; // 234

	return 0;
}
Bochs源码分析 - 8:bochs的CPU代码初步分析 前言 上一篇文章,我们分析了floppy设备的初始化,本来我们希望看看floppy的工作原理,但是调试时发现其运行cpu,通过BIOS启动指令来调用floppy。(从现在来看这是肯定的,floppy是外设,要想调用必须通过cpu,还是自己对底层不太熟悉) Bochs的CPU模块特别复杂,函数众多,我们是第一次分析,对其结构还是不太熟悉,我们先尝试来看其执行流程。在分析前,我浏览了一遍喻强老师的《Bochs项目源码分析与注释》,其CPU模块的核心图如下。 CPU模块的... 阅读详情

相关推荐

Bochs源码分析 - 26:8259中断控制器介绍

前言 现在我们跟着《x86/x64体系探索及编程》来分析17章内容 -- 8259中断控制器。这个是涉及硬件的,很遗憾,除了大学期间使用STM32搞过一个计算器,其余就没多少硬件编程经验,我在淘宝上找了下大概是这个东东。 https://pdos.csail.mit.edu/6.828/2010/readings/hardware/8259A.pdf 上面是8259A的芯片手册,里面讲的还是挺详细的,虽然里面很多东西还是看不太懂,但是结合着《x86/...

WriteAnything_的博客 964

启用分页机制

启用分页机制

weixin_42888638的博客 1037

Bochs 项目源码分析与注释

Chapter 1 x86 体系结构与PC 系统概要.....................................1 1.1 x86 CPU 结构...............................................................................................................1 1.1.1 冯诺依曼架构和CISC 指令集......................................................................1 1.1.2 CPU 结构........................................................................................................1 1.1.3 CPU 工作模式................................................................................................2 1.2 x86 体系结构概览........................................................................................................3 1.3 PC 系统.........................................................................................................................5 1.3.1 PC 系统概述...................................................................................................5 2.3.2 总线拓扑.........................................................................................................6 2.3.3 存储器与I/O 编址.........................................................................................6 2.3.4 关于系统的启动与引导.................................................................................8 Chapter 2 Bochs 工程概述....................................................... 11 2.1 开源项目Bochs 介绍.................................................................................................11 2.2 版本2.2.1 源码组织..................................................................................................11 2.3 工程类结构.................................................................................................................12 2.4 主体框架结构分析.....................................................................................................13 2.4.1 Bochs 工程中的重要类................................................................................13 (1) VM 控制台界面类.............................................................................................13 (2) CPU 模拟............................................................................................................14 (3) Memory 模拟......................................................................................................14 (4).I/O device 模拟...................................................................................................15 2.4.2 入口函数main()及Win32 Gui 初始化........................................................15 2.5 Bochs 的工作方式......................................................................................................18 Chapter 3 CPU 类的源码分析...................................................20 3.1 CPU 类概述................................................................................................................20 3.1.1 CPU 逻辑结构框图......................................................................................20 3.1.2 类BX_CPU_C 成员归纳.............................................................................20 3.2 类BX_CPU_C 源码分析..........................................................................................21 3.2.1 CPU 特性声明..............................................................................................21 3.2.2 类bxInstruction_c 成员分析........................................................................22 3.2.3 类BX_CPU_C 源码注释.............................................................................22 3.3 通用寄存器.................................................................................................................29 3.3.1 数据结构与注释...........................................................................................29 3.3.2 通用寄存器归纳...........................................................................................30 3.4 段寄存器、全局寄存器GDI 和IDT ........................................................................31 3.4.1 数据结构与注释...........................................................................................31 3.4.2 段寄存器结构分析.......................................................................................33 3.5 CPU 状态字EFLAGS................................................................................................35 3.5.1 数据结构与注释...........................................................................................35

shoelace源代码分析,bochs调试过程

b 0x10035 c (0) Breakpoint 1, 0x10035 in ?? () Next at t=75292653 (0) [0x00010035] 1000:0035 (unk. ctxt): call 0x504                ; e8cc04 s Next at t=75292654 (0) [0x00010504] 1000:0504 (u

linux-0.11调试教程 1742

Bochs项目源码分析与注释

Bochs项目源码分析与注释 Table of Content Chapter 1 x86 体系结构与 PC 系统概要1 1.1 x86 CPU 结构1 1.1.1 冯诺依曼架构和CISC 指令集 1.1.2 CPU 结构 1.1.3 CPU 工作模式 1.2 x86 体系结构概览 1.3 PC 系统 1.3.1 PC 系统概述 2.3.2 总线拓扑 2.3.3 存储器与I/O 编址 2.3.4 关于系统的启动与引导 Chapter 2 Bochs 工程概述 2.1 开源项目Bochs 介绍........................................11 2.2 版本2.2.1 源码组织..................................................................................................11 2.3 工程类结构.................................................................................................................12 2.4 主体框架结构分析.....................................................................................................13 2.4.1 Bochs 工程中的重要类................................................................................13 (1) VM 控制台界面类.............................................................................................13 (2 ) CPU 模拟............................................................................................................14 (3) Memory 模拟......................................................................................................14 (4 ).I/O device 模拟...................................................................................................15 2.4.2 入口函数main()及Win32 Gui 初始化........................................................15 2.5 Bochs 的工作方式......................................................................................................18 Chapter 3 CPU 类的源码分析...................................................20 3.1 CPU 类概述................................................................................................................20 3.1.1 CPU 逻辑结构框图......................................................................................20 3.1.2 类BX_CPU_C 成员归纳.............................................................................20 3.2 类BX_CPU_C 源码分析..........................................................................................21 3.2.1 CPU 特性声明..............................................................................................21 3.2.2 类bxInstruction_c 成员分析........................................................................22 3.2.3 类BX_CPU_C 源码注释.............................................................................22 3.3 通用寄存器.................................................................................................................29 3.3.1 数据结构与注释...........................................................................................29 3.3.2 通用寄存器归纳...........................................................................................30 3.4 段寄存器、全局寄存器GDI 和IDT ........................................................................31 3.4.1 数据结构与注释...........................................................................................31 3.4.2 段寄存器结构分析.......................................................................................33 3.5 CPU 状态字EFLAGS................................................................................................35 3.5.1 数据结构与注释...........................................................................................35 Understanding the source code of bochs

Bochs 源码

Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。事实上,它可以在任何编译运行Bochs的平台上模拟x86硬件。通过改变配置,可以指定使用的CPU(386、486或者586),以及内存大小等。一句话,Bochs是电脑里的“PC”。根据需要,Bochs还可以模拟多台PC,此外,它甚至还有自己的电源按钮。

Bochs源码分析 - 2:使用bochs运行引导代码

前言 这一篇文章中,我们尝试使用编写引导代码,然后配置bochs让其可以运行这份代码,过程中遇到的问题,为什么这么做,我会尽可能详细的描述给大家,当然自己可能存在错误,请见谅!! 安装 nasm 编译器 ...

WriteAnything_的博客 1309

bochs-2.6.8源码

对于模拟x86架构,编写自己的操作系统练习非常有帮助。

Bochs源码安装及运行调试

最近在读《Orange's一个操作系统的实现》,开始部分介绍了虚拟机Bochs的安装及调试,本文把折腾过程做下记录。 操作系统:Ubuntu10.04(最新的版本老是有问题) 软件版本:bochs 2.3.5(和书中保持一致) 1 更新Ubuntu 由于ubuntu 10.04是很老的版本,早在2016年已停止了更新支持,直接sudo apt-get update会失败,好在ubuntu提供了...

weiwei22844的专栏 2357

【免积分】小型开源虚拟机bochs源码

迷你型的开源虚拟机bochs的源代码,最新的2.4.1版本..........

虚拟机Bochs的源代码(VC6工程,3.4M)

著名虚拟机Bochs的源代码。开发底层程序可少不了虚拟机,常用的虚拟机有VMWare,Virtual PC,当然,这些都不开放源代码的,开源的就是Bochs了。查了一下,论坛上只有虚拟机程序,没有源代码,这里贴出来吧。版本2.1.1。在VC6下顺利编译成功。

Bochs源码分析 - 0 文章集合

为什么要阅读Bochs源码 Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。事实上,它可以在任何编译运行Bochs的平台上模拟x86硬件。通过改变配置,可以指定使用的CPU(386、486或者586),以及内存大小等。一句话,Bochs是电脑里的“PC”。根据需要,Bochs还可以模拟多台PC,此外,它甚至还有自己的电源按钮。 ...

WriteAnything_的博客 1801

MATLAB实战:用ARMAX模型搞定电力系统惯量评估(附完整代码)

本文详细介绍了如何利用MATLAB中的ARMAX模型进行电力系统惯量评估,解决新能源占比提高带来的系统惯量下降问题。通过系统辨识技术,从电网运行数据中准确提取惯量参数,并提供完整的代码实现,帮助工程师快速应用于实际工程。

peach的博客 631

基于 Bochs 的操作系统内核实现

简介 Bochs 简介 Bochs(读音Box)是一个开源的模拟器(Emulator),它可以完全模拟x86/x64的硬件以及一些外围设备。与VirtualBox / VMware等虚拟机(Virtual Machine)产品不同,它的设计目标在于模拟一台真正的硬件,并不追求执行速度的高效,而追求模拟环境的真实,同时带有强大的调试功能,比如观察寄存器、对实地址/虚拟地址下断点、装载符号

xyjikl 4177

AAAI2024最佳解读|FontDiffuser One-Shot Font Generation via Denoising Diffusion with Multi-Scal

本文提出了一种名为FontDiffuser的基于扩散的单次字体生成方法,旨在通过去噪扩散模型生成模仿参考图像风格的字体,同时保留源图像的内容。尽管现有的字体生成方法在性能上取得了一定的进展,但在处理复杂字符和大风格变化时仍面临挑战。FontDiffuser通过引入多尺度内容聚合(MCA)模块,有效结合不同尺度的全局和局部内容线索,从而增强复杂字符的笔画保留能力。此外,文章还提出了一种风格对比细化(SCR)模块,用于风格表示学习,利用风格提取器从图像中分离风格,并通过精心设计的风格对比损失来监督扩散模型。

haimianxiaobao11的博客 1180

Kisssoft软件在行星齿轮设计上的初试

行星齿轮传动与链传动相比较,具有质量小,体积小,承载能力强,传动比大,传动效率高等优点,但在行星齿轮传动种种优点下,不可避免的带来一些缺点,对其材料的要求过高,在追求传动比大而体积小的同时,其传动结构大大的复杂化,以及在制造和安装过程中较困难,对于行星齿轮传动设计来说,不仅应该了解其优点,而且应该在设计中,充分发挥其优点,且把其缺点降低到最低的限度。从而才能设计出性能优良的行星齿轮传动装置,为我们赛车提供更加强大的动力保证。 Kisssoft软件为我们行星齿轮传动设计提供了一体化方案,从设...

m0_69808569的博客 1万+

IDA&&BOCHS调试MBR

一、说明 IDA都很熟悉,强大的逆向工具。 Bochs是一个x86硬件平台的开源模拟器。它可以模拟各种硬件的配置。Bochs模拟的是整个PC平台,包括I/O设备、内存和BIOS。更为有趣的是,甚至可以不使用PC硬件来运行Bochs。对于调试操作系统是灰常强大的。说白了就是一个虚拟机。   二、IDA调试MBR IDA调试MBR比较简单,先配置下虚拟机的VMX文件,添加一下代码: [A...

kingswb的博客 2366

告别Python中间件!C#原生调用YOLOv11/v12:工业视觉检测零语言壁垒全流程

本文介绍了一种基于C#和ONNX Runtime的工业视觉检测解决方案,解决了传统YOLO模型在工业应用中面临的三大痛点:语言壁垒、性能损耗和模型更新困难。该系统采用三层架构设计,支持C#原生调用YOLO模型,无需中间件,性能损耗低于5%,满足工业产线30FPS+的实时性要求。文章详细阐述了环境搭建、模型导出规范、核心代码实现及工业级优化方案,提供可直接用于生产环境的完整流程,实现了训练与部署的解耦,显著降低了维护成本。该方案兼容主流YOLO版本,支持全平台部署,为工业视觉检测提供了高效可靠的C#集成方案。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 179

最新爱叶解析接口搭建php网站源码 附4k画质测试效果

介绍: 测试地址http://118.89.95.50/ayy/? url=https://m.v.qq.com/x/cover/m/mzc00200a7ghbkc.html 测试接口http://118.89.95.50/ayy/? url= 网盘下载地址: https://zijiewangpan.com/lDBTVAAN3by 图片:

SEO资源下载 1152

计算机视觉教程1-1:透视空间与透视变换

在生活中,透视现象很常见,其物理本质是光的直线传播。由于人眼与相机在捕获图像时均存在透视现象,因此计算机几何基于透视空间进行研究。本节介绍透视变换原理

FRIGIDWINTER的博客 3084

【Matlab】如何使用Simulink进行电池建模和SOC预估

“通过Simulink电池建模进行SOC预估,其实挺容易!” 1 声明 本文只描述一般性电池建模方法,文中出现的电池相关数据来自一些论文或者外文文献,对数据的真实性不做任何保证。 本文参考了不少国内高校的硕士论文和外文文献,所以本篇文章只作为学术性交流,未经...

wanff1204的博客 2万+

全网高清视频下载器4k源码

点我下载

ZXEO博客 395

26、机器学习模型的成员推断攻击与隐私保护

本文探讨了机器学习模型面临的成员推断攻击及其对隐私的潜在威胁。通过使用CIFAR-10数据集,详细介绍了如何利用影子模型和攻击模型推断特定数据点是否属于模型的训练集。实验表明,即使无法直接访问模型参数和原始数据,攻击者仍能以高于随机猜测的概率进行推断,从而构成隐私风险。此外,文章还分析了实验的关键技术点,并提出了多种隐私保护建议,包括数据脱敏、差分隐私、模型正则化等方法。

coffee的博客 121

x86汇编学习历程1----bochs

一.基础 8086基础: 注:截图自https://www.processon.com/view/5b2b0229e4b0d4a19d7eeaf6#map 二.虚拟机安装 略 三.bochs使用 在botchs官网下载最新版本安装 注:需要提前创建好虚拟硬盘,以下为写入虚拟硬盘主引导扇区的代码 mov ax, 0x30 mov dx, 0xC0 add ax, dx times 502 db 0 ;重复此位指令‘db 0’502次 db 0x55 db 0xAA 双击Disk&Boo

qq_41420788的博客 494

堆外内存 OOM:现象分析与优化方案

本文分析了 Java 中堆外内存泄漏及其引发的 OOM 问题,重点讨论了主动申请未释放和 JNI 调用未释放的两大原因。提供了排查策略,如启用 Native Memory Tracking(NMT)和监控堆外内存使用。并提出了优化方案,包括合理管理堆外内存、设置内存限制及定期监控,帮助避免内存泄漏对系统性能的影响。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 14万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

上一篇: Bochs源码分析 - 23:页表构建的汇编分析
下一篇: Bochs源码分析 - 25:关于内存寄存器及属性有关机制说明
WriteAnything_
博客等级 码龄5年 66粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值