小编Mic*_*tch的帖子

Linux内核header.S来源,为什么_end + 3在归零BSS时需要?

在Linux源代码树中,文件arch/x86/boot/header.S具有类似于此的x86代码,以便在被调用之前清除BSS部分main:

...
# Zero the bss
    movw    $__bss_start, %di
    movw    $_end+3, %cx
    xorl    %eax, %eax
    subw    %di, %cx
    shrw    $2, %cx
    rep; stosl
...
Run Code Online (Sandbox Code Playgroud)

为什么_end地址中添加了3个?为什么不movw $_end, %cx代替movw $_end+3, %cx

linux x86 assembly linux-kernel bootloader

7
推荐指数
1
解决办法
236
查看次数

这段 x86-64 代码中的 lea 有什么作用?

这是函数的前四行。我知道前两行在堆栈中创建一个新框架,基本上是“设置”行。lea 指令有什么作用?

40148e: 48 83 ec 18    sub    $0x18,%rsp
401492: 48 89 f2       mov    %rsi,%rdx
401495: 48 8d 4e 04    lea    0x4(%rsi),%rcx
401499: 48 8d 46 14    lea    0x14(%rsi),%rax
Run Code Online (Sandbox Code Playgroud)

assembly x86-64

7
推荐指数
1
解决办法
2万
查看次数

函数参数传入Linux内核中断处理程序(从asm到C)

当我阅读Linux内核源码时,我遇到了这段代码:

__visible void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)   
{
    struct pt_regs *old_regs = set_irq_regs(regs);

    entering_ack_irq();
    local_apic_timer_interrupt();
    exiting_irq();

    set_irq_regs(old_regs);
}
Run Code Online (Sandbox Code Playgroud)

该函数smp_apic_timer_interrupt()有一个参数.调用此函数是通过一段汇编语言代码:

ENTRY(apic_timer_interrupt)
     RING0_INT_FRAME;     
     ASM_CLAC;           
     pushl_cfi $~(0xef);
     SAVE_ALL;         
     TRACE_IRQS_OFF
     movl %esp,%eax;
     call smp_apic_timer_interrupt; // <------call high level C function       
     jmp ret_from_intr;      
     CFI_ENDPROC;           
ENDPROC(apic_timer_interrupt)
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚高级C函数如何smp_apic_timer_interrupt()获取其参数(通过哪个寄存器)?

x86 assembly calling-convention linux-kernel interrupt-handling

7
推荐指数
2
解决办法
1225
查看次数

近呼叫/跳转表并不总是在引导加载程序中工作

一般问题

我一直在开发一个简单的引导加载程序,并且在某些环境中偶然发现问题,这些环境中的指令不起作用:

mov si, call_tbl      ; SI=Call table pointer
call [call_tbl]       ; Call print_char using near indirect absolute call
                      ; via memory operand
call [ds:call_tbl]    ; Call print_char using near indirect absolute call
                      ; via memory operand w/segment override
call near [si]        ; Call print_char using near indirect absolute call
                      ; via register
Run Code Online (Sandbox Code Playgroud)

这些中的每一个碰巧涉及间接接近CALL到绝对存储器偏移.我发现如果我使用类似的JMP表,我会遇到问题.相对的呼叫和跳转似乎没有受到影响.像这样的代码有效:

call print_char 
Run Code Online (Sandbox Code Playgroud)

我已经通过海报讨论了Stackoverflow上提出的建议,讨论了编写引导加载程序的注意事项.特别是我看到这个Stackoverflow回答了一般的Bootloader技巧.第一个提示是:

  1. 当BIOS跳转到您的代码时,您不能依赖具有有效或预期值的CS,DS,ES,SS,SP寄存器.应在引导加载程序启动时正确设置它们.您只能保证将从物理地址0x07c00加载并运行引导加载程序,并将引导驱动器号加载到DL寄存器中. …

x86 assembly real-mode nasm bootloader

7
推荐指数
1
解决办法
584
查看次数

使用".intel_syntax noprefix"如何获取标签的内存地址?

我正在学习如何创建组装和链接的真实模式程序:

  • GCC汇编程序版本2.25
  • Binutils版本2.25
  • GCC版本5.2.0

我使用没有指定前缀的Intel语法 .intel_syntax noprefix

我想将字符串的地址加载到SI寄存器中.我知道,如何在NASM中引用内存位置,但是当我在GNU汇编程序代码中执行相同操作时,它只将字符串的WORD移动到寄存器而不是标签的地址.

我的代码是:

.code16
.intel_syntax noprefix

mov cx, 11
mov si, name
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)

当我用GCC编译它时,我可以在调试器中看到处理器执行的操作:

mov si, WORD ptr ds:0x7d2d
Run Code Online (Sandbox Code Playgroud)

但我想将字符串的地址移入寄存器,而不是它指向的数据.

我还尝试在名称周围放置方括号,如下所示:

.code16
.intel_syntax noprefix

mov cx, 11
mov si, [name]
mov di, 0x7E00
push di
rep cmpsb
pop di
je LOAD
Run Code Online (Sandbox Code Playgroud)

它没有任何区别.

NASM我知道这个汇编代码有效:

mov si, name
Run Code Online (Sandbox Code Playgroud)

NASM将生成将地址移动name到寄存器SI的指令.

我的问题:有没有办法强制GCC使用带有无前缀的英特尔语法将符号的地址加载到寄存器中?

x86 assembly real-mode gnu-assembler intel-syntax

7
推荐指数
1
解决办法
3189
查看次数

有没有办法在没有xml或属性文件的情况下在应用程序上下文中存储java变量/对象

我想在 Spring Boot 应用程序的应用程序上下文中存储一个特定的变量(字符串或对象)。但我不想使用 xml 或属性文件来存储它。

将有一个函数将数据存储在应用程序上下文中。我应该能够检索它、修改它、删除它或添加更多数据。

基本上我想在初始化完成后将数据存储在应用程序上下文中。

java spring applicationcontext spring-boot

7
推荐指数
2
解决办法
1万
查看次数

java.lang.IllegalStateException:ApplicationEventMulticaster未初始化 - 在通过上下文组播事件之前调用'refresh'

我正在尝试创建一个Spring Boot项目.

pom.xml中:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.java</groupId>
  <artifactId>spring-boot-example</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Java Spring Boot Example</name>
  <parent>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-parent</artifactId>  
    <version>1.4.2.RELEASE</version>  
</parent>    
<dependencies>  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
    </dependency> 

    </dependencies>  
<properties>  
    <java.version>1.8</java.version>  
</properties>  
</project>
Run Code Online (Sandbox Code Playgroud)

SpringBootExample.java:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication 
public class SpringBootExample {

    public static void main(String[] args) {
         SpringApplication.run(SpringBootExample.class, args);  
    }
}
Run Code Online (Sandbox Code Playgroud)

当尝试将上述类作为Java应用程序执行时,我收到错误:

2017-06-21 17:07:14.125 ERROR 7860 --- [main] osbfsDefaultListableBeanFactory:名为'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory'的bean上的Destroy方法引发异常

java.lang.IllegalStateException:ApplicationEventMulticaster未初始化 - 在通过上下文组播事件之前调用'refresh':org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@63f509:启动日期[Wed Jun 21 17:07:06 EDT 2017]; org.springframework.context.support上的org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:404)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]中的上下文层次结构的根org.springframework.beans.factory.support.DisposableBeanAdapter.destroy中的.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97)〜[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE](DisposableBeanAdapter.java: 253)〜[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578)[spring-beans-4.3. 4.RELEASE.jar:4.3.4.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554)[spring-beans-4.3.4.RELEASE.jar:4.3.4.发布在org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListable)BeanFactory.java:954)[spring-beans-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523)[spring-beans] -4.3.4.RELEASE.jar:4.3.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:961)[spring-beans-4.3.4.RELEASE.jar:4.3 .4.RELEASE]在org.springframework.context的org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1033)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE]. support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:555)[spring-context-4.3.4.RELEASE.jar:4.3.4.RELEASE] org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java: …

spring spring-boot

7
推荐指数
1
解决办法
2万
查看次数

Tiny C Compiler生成的代码会发出额外的(不必要的?)NOP和JMP

有人可以解释为什么这个代码:

#include <stdio.h>

int main()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当使用tcc使用tcc编译时,生成这个asm:

00401000  |.  55               PUSH EBP
00401001  |.  89E5             MOV EBP,ESP
00401003  |.  81EC 00000000    SUB ESP,0
00401009  |.  90               NOP
0040100A  |.  B8 00000000      MOV EAX,0
0040100F  |.  E9 00000000      JMP fmt_vuln1.00401014
00401014  |.  C9               LEAVE
00401015  |.  C3               RETN
Run Code Online (Sandbox Code Playgroud)

我猜可能是

00401009  |.  90   NOP
Run Code Online (Sandbox Code Playgroud)

也许有一些内存对齐,但是怎么样

0040100F  |.  E9 00000000     JMP fmt_vuln1.00401014
00401014  |.  C9              LEAVE
Run Code Online (Sandbox Code Playgroud)

我的意思是为什么编译器会插入跳转到下一条指令的近跳转,LEAVE会执行呢?

我在64位Windows上使用TCC 0.9.26生成32位可执行文件.

c x86 assembly tcc compiler-optimization

7
推荐指数
2
解决办法
525
查看次数

发送到不处于等待 SIPI 状态的活动 AP 的启动 IPI 会发生什么情况

在之前的Stackoverflow 回答中,玛格丽特·布鲁姆 (Margaret Bloom) 说道:

\n\n
\n

唤醒 AP

\n\n

这是通过向所有 AP 发出 INIT-SIPI-SIPI (ISS) 序列来实现的。

\n\n

将发送 ISS 序列的 BSP 使用“全部排除自身”简写作为目的地,从而针对所有 AP。

\n\n

SIPI(启动处理器间中断)会被所有在收到 SIPI 时被唤醒的 CPU 忽略,因此,如果第一个 SIPI 足以唤醒目标处理器,则第二个 SIPI 将被忽略。出于兼容性原因,英特尔建议这样做。

\n
\n\n

我多年来一直在编写多处理代码,我对硬件的观察是,在某些处理器上,它似乎与所述不同。我很确定我已经观察到应用处理器 (AP) 在收到启动 IPI 后修改了其指令指针,即使它处于活动状态(不在等待启动 IPI 中)。

\n\n

是否有任何英特尔文档说明 AP在不处于等待启动 IPI 状态时收到启动 IPI 后将执行的操作,或将行为记录为未定义?我似乎无法在英特尔软件文档手册或补充英特尔文档Minimal Boot Loader for Intel\xc2\xae Architecture中找到明确的答案。

\n\n

通常,我编写初始化代码来初始化并启动 AP,假设 AP 可以获取 SIPI 并在活动状态(而不是等待启动 IPI 状态)下重置其指令指针。

\n\n

我正在尝试确定 Margaret Bloom 声明的准确性,即先前已唤醒的 …

boot x86 multicore intel osdev

7
推荐指数
1
解决办法
3014
查看次数

用int 13h读取硬盘驱动器写入扇区

我有一个简单的程序.它必须从硬盘驱动器(而不是mbr)读取第一个扇区,并将其写入0扇区(mbr).但它不起作用.我认为它与错误的DAP有关.谢谢.

    [bits   16]
    [org    0x7c00]

;clear screen
start:
    mov     ax, 0x3
    int     0x10

;reset the hard drive
    xor     ah, ah
    mov     dl, 0x80
    int     0x13
    jnz     error

;read the second sector
    mov     si, DAP
    mov     ah, 0x42
    int     0x13

    mov     si, data
    call    print_string
    jmp     $

DAP:
    db      0x10    ;size of DAP
    db      0x0     ;zero
    db      0x1     ;number of sectors to read
    db      0x0     ;zero
;point to memory
    dw      0x0     ;offset
    dw      0x0     ;segment
    dq      0x1     ;disk address

DAP2:
    db …
Run Code Online (Sandbox Code Playgroud)

x86 assembly bios bootloader bochs

6
推荐指数
2
解决办法
1万
查看次数