程序集 32 位打印显示在 qemu 上运行的代码,无法在真实硬件上运行

2023-12-20

我已经用 x86 汇编语言编写了一小段在裸硬件上运行的代码,此时,它已启用受保护的 32 位模式

然而,我遇到了与屏幕打印有关的问题。我读到,要在不中断的情况下执行此操作,可以将字符加载到特殊的内存区域,即 RAM 地址 0xb8000。

知道这一点后,我编写了一个函数来实现这一点,并且在 qemu 中测试时证明它是成功的。然而,问题来了,当我尝试在真机(即联想 G470 笔记本电脑)上运行该程序时,它无法显示我想要通过写入显示内存区域来显示的字符串。使用 BIOS 中断显示的所有其他字符串均按预期工作,可惜 32 位打印功能似乎没有执行任何操作。但程序不会崩溃,并且在使用中断打印的行之后会出现一个闪烁的光标。

如果它很重要,我会尝试从 USB 驱动器启动它

更直白地说,字符串 S3 没有在我的笔记本电脑中打印,而是在 qemu 中打印,我不知道为什么。

这是我的代码,对于缺乏技巧,我提前表示歉意:

[BITS 16]                       ;NASM 16-BIT MODE
[ORG 0x7C00]                    ;OFFSET MEMORY LOCATIONS TO BSECTOR/ BIOS LOADS MBR INTO THIS ADDRESS.
XOR AX, AX                      ;INITIALIZE SEGMENT REGISTERS BY AX    
MOV DS, AX                      ;INDIRECTLY INITIALIZING DS REGISTER
MOV ES, AX                      ;INDIRECTLY INITIALIZING ES REGISTER
MOV GS, AX                      ;INDIRECTLY SETTING GS REGISTER
MOV FS, AX                      ;INDIRECTLY SETTING DS REGISTER
MOV SP, 0X900                   ;SETTING STACK POINTER TO 0X900, OFFSET FROM 0X0 = 0X7C00
MOV BP, SP                      ;
JMP WORD 0x0:START16            ;JUMP TO START OF PROGRAM

PSR16B:                         ;16-BIT PRINT ROUTINE
  MOV SI, BX                ;ASSIGN SI POSITION OF STRING
  MOV AH, 0XE               ;TTY MODE
PSR16BLOP0:                  ;PRINT LOOP
     LODSB                  ;LOAD SI INTO AL AND +1 ADDRESS OF STRING
     CMP AL, 0X0            ;CONDITIONAL
     JE PSR16LOP0END        ;END LOOP
     INT 0X10               ;BIOS INTERRUPT, PRINT AL TO SCREEN
     JMP PSR16BLOP0         ;LOOP TO LOP
PSR16LOP0END:                ;END OF LOOPA
  MOV AL, 0XA               ;NEW LINE ASCII
  INT 0X10                  ;RAISING PRINT BIOS INTERRUPT
  MOV AL, 0XD               ;NEWLINE 'CHARACTER' ASCII
  INT 0X10                  ;RAISING PRINT BIOS INTERRUPT
  ADD CH, 0X1               ;ADD ONE TO COUNTER
  RET                       ;RETURN TO LAST ADRESS BEFORE CALL 
PSR16BEND:                      ;END OF FUNCTION, UNUSED

S0:                             ;STRING
    DB 'BOOTING SEQUENCE INITIALIZED',0
S1:                             ;STRING
    DB 'LOADING GDT',0
S2:                             ;STRING
    DB 'ENTERING 32-BIT PROTECTED MODE',0

GDTS:                           ;START OF GLOBAL DESCRIPTOS TABLE

       GDTN:                           ;NULL BEGGINING, 8 BYTES
       DQ 0X0
  GDTC:                           ;TABLE FOR CODE SEGMENT
       DW 0XFFFF               ;BITS 0-15 OF LIMIT(MAXADRESSUNIT) ||0X0-0XF
       DW 0X0                  ;BASE(SEGMENTSTART), BITS 0-15 ||0XF-0X1F
       DB 0X0                  ;BASE, BITS 16-23 ||0X20-0X27
       DB 10011010B            ;ACCESS BYTE ||0X28-0X2F
       DB 11001111B            ;SECOND4BITS:LIMITBITS 16-19/FIRST4BITS:FLAGS= ||0X30-0X37
       DB 0X0                  ;BASE, BITS 24-31||0X38-0X3F
  GDTD:                           ;TABLE FOR DATA SEGMENT
       DW 0XFFFF               ;BITS 0-15 OF LIMIT(MAXADRESSUNIT) ||0X0-0XF
       DW 0X0                  ;BASE(SEGMENTSTART), BITS 0-15 ||0XF-0X1F
       DB 0X0                  ;BASE, BITS 16-23 ||0X20-0X27
       DB 10010010B            ;ACCESS BYTE ||0X28-0X2F
       DB 11001111B            ;SECOND4BITS:LIMITBITS 16-19/FIRST4BITS:FLAGS= ||0X30-0X37
       DB 0X0                  ;BASE, BITS 24-31||0X38-0X3F
GDTE:                           ;END OF GLOBAL DESCRIPTION TABLE

GDTDESC:                        ;GDT DESCRIPTOR
    DW GDTE - GDTS - 1      ;SIZE OF GDT, 2 BYTE, MUST BE LESS THAN 1
    DD GDTS                 ;ADRESS OF GDT, 4 BYTE
GDTDESCEND:                     ;END OF GDTDESC, UNUSED

CODESEG EQU GDTC - GDTS         ;CODE SEGMENT ADDRESS CONSTANT
DATASEG EQU GDTD - GDTS         ;DATA SEGMENT ADDRESS CONSTANT

START16:                        ;START OF BOOTSECTOR PROGRAM
    MOV CH, 0X0             ;LINES COUNTER.
    MOV BX, S0              ;SET STRING POINTER
    CALL PSR16B             ;CALL PRINT FUNCTION
    MOV BX, S1              ;SET STRING POINTER
    CALL PSR16B             ;CALL PRINT FUNCTION
    LGDT [GDTDESC]          ;LOADING GDT DESCRIPTOR
    MOV BX, S2              ;SET STRING POINTER
    CALL PSR16B             ;CALL PRINT FUNCTION
    CLI                     ;SEVERING INTERRUPTS
    MOV EAX, CR0            ;INDIRECTLY SETTING PROTECTED MODE BIT
    OR EAX, 0X1             ;SETTING PMODE BIT
    MOV CR0, EAX            ;PROTECTED MODE ENABLED
    JMP CODESEG:START32     ;FAR JUMP TO 32 BIT LAND

[BITS 32]                       ;NASM 32-BIT MODE

S3:                             ;STRING
    DB '32-BIT PROTECTED MODE ENABLED', 0

PSR32B:                        ;PRINT TO DISPLAY ROUTINE FOR 32-BIT   PREOTECTED MODE
 PSR32BLOP0:             ;INITIALIZE VGA REGION POINTER
  CMP CL, 0X0          ;CONDITIONAL, IF FALSE SKIP INITIALIZATION
  JNE PSR32BLOP0END    ;END LOOP
  MOV EBX, 0XB8000      ;INITIALIZING POINTER TO VGA MEMORY REGION
  ADD CL, 0X1          ;ADD TO COUNTER
  JMP PSR32BLOP0       ;LOOP
 PSR32BLOP0END:             ;END OF FUNCTION

 PSR32BLOP1:             ;USED TO INTIALIZE VGA MEMORY POINTER, NEWLINE OFFSET FROM 16-BIT LINES
      CMP CH, 0X0         ;END CONDITIONAL
     JE PSR32BLOP1END;    ;JUMP TO END OF LOOP
     ADD EBX, 0XA0        ;ADD EQUIVALENT OF ONE LINE TO POINTER
     SUB CH, 0X1         ;LOOP END COUNTER
     JMP PSR32BLOP1    ;LOOP
 PSR32BLOP1END:          ;USED TO INTIALIZE VGA MEMORY POINTER, END
    MOV ESI, EDX            ;LOAD LODSW STRING POINTER WITH APPROPIATE ADDRESS
    MOV AH, 0X0F            ;BLACK BACKGROUND, WHITE LETTERS
  PSR32BLOP2:                ;PRNTINH LOOP
     LODSB                    ;LOAD CHARACTER INTO AL
     CMP AL, 0X0             ;CHECK FOR END OF STRING
     JE PSR32BLOP2END         ;IF AX IS 0 JUMP TO END OF LOOP
     MOV [EBX], AX           ;LOAD WORD CHARACTER INTO VGA MEMORY
     ADD EBX, 0X2             ;MOVE TO NEXT CHARACTER WORD IN MEMORY ADDRESS
     JMP PSR32BLOP2           ;LOOP BACK TO START
 PSR32BLOP2END:              ;END OF LOOP

    RET
 ENDPSR32B:                     ;END OF FUNCTION, UNUSED


 START32:                        ;START OF 32 BIT PROTECTED PROGRAM
    MOV AX, DATASEG        ;SET DATA SEGMENT ADDRESS TO POINTER
    MOV DS, AX              ;INITIALIZING SEGMENT REGISTERS
    MOV SS, AX              ;INITIALIZING SEGMENT REGISTERS
    MOV [ES:DI], DL              ;INITIALIZING SEGMENT REGISTERS
    MOV DS, AX              ;INITIALIZING SEGMENT REGISTERS
    MOV GS, AX              ;INITIALIZING SEGMENT REGISTERS
    MOV EDX, S3              ;STRING POINTER DX
    CALL PSR32B             ;CALL PRINT ROUTINE// THIS IS A TEST
    JMP $                   ;LOOP TO INFINITY



 PAD:                          ;BOOTSECTOR PADDING & MAGIC NUMBER
    TIMES 510-($-$$) DB 0   ;FILL 0S TO END OF SECTOR
    DW 0xAA55               ;BOOT SIGNATURE

编辑:在start32处将CL设置为0:解决了问题


您的代码存在许多严重问题:

  • 它全部是大写并且难以阅读。
  • 似乎缺乏对实模式如何理解段:偏移寻址 https://thestarman.pcministry.com/asm/debug/Segments.html在实模式下工作。
  • 寄存器在未初始化的情况下使用。
  • 段寄存器设置不正确。

执行类似操作的代码版本如下。代码大部分都带有注释。需要了解的重要事项:

  • 当 BIOS 打印字符时,它会更新当前行和列BIOS 数据区 (BDA) http://stanislavs.org/helppc/bios_data_area.html。在保护模式下,您可以读取内存位置 0x450(列)和 0x451(行)中的字节。您可以使用此信息从 BIOS 中断处继续。
  • 内存地址0x44a处的16位字是BIOS先前设置的当前视频模式的屏幕宽度。
  • 屏幕上的每个单元格都是两个字节。视频内存中的当前字节偏移量可以计算为 0xb8000+(cur_row * screen_width + cur_col) * 2
  • 包括一个BIOS 参数块 (BPB) https://en.wikipedia.org/wiki/BIOS_parameter_block允许在软盘 (FDD) 模拟模式下使用 USB 磁盘介质时正确加载映像。此代码为 1.44MiB 软盘提供 BPB。
  • 要正确寻址所有内存,您应该启用A20线 https://wiki.osdev.org/A20_Line.提供的代码使用快速启用方法,但可能不与所有硬件兼容,但应该适用于大多数模拟器。
  • 当使用打印字符串时print_string_pm硬件光标位置更新为set_cursor将字符串放入显示内存后。

bpb.inc:

global bpb_disk_info

    jmp boot_start
    TIMES 3-($-$$) DB 0x90   ; Support 2 or 3 byte encoded JMPs before BPB.

bpb_disk_info:
    ; Dos 4.0 EBPB 1.44MB floppy
    OEMname:           db    "mkfs.fat"  ; mkfs.fat is what OEMname mkdosfs uses
    bytesPerSector:    dw    512
    sectPerCluster:    db    1
    reservedSectors:   dw    1
    numFAT:            db    2
    numRootDirEntries: dw    224
    numSectors:        dw    2880
    mediaType:         db    0xf0
    numFATsectors:     dw    9
    sectorsPerTrack:   dw    18
    numHeads:          dw    2
    numHiddenSectors:  dd    0
    numSectorsHuge:    dd    0
    driveNum:          db    0
    reserved:          db    0
    signature:         db    0x29
    volumeID:          dd    0x2d7e5a1a
    volumeLabel:       db    "NO NAME    "
    fileSysType:       db    "FAT12   "

boot.asm:

bits 16
ORG 0x7c00

VIDEO_TEXT_ADDR     EQU 0xb8000 ; Hard code beginning of text video memory
ATTR_WHITE_ON_BLACK EQU 0x07    ; White on black attribute

CR                  EQU 0x0d    ; Carriage return
LF                  EQU 0x0a    ; Line feed

; Include a BPB (1.44MB floppy with FAT12) to be more comaptible with USB floppy media
%include "bpb.inc"

boot_start:
    xor ax, ax                  ; DS=SS=0. Real mode code below doesn't use ES
    mov ds, ax
    mov ss, ax                  ; Stack at 0x0000:0x7c00 below bootloader
    mov sp, 0x7c00
    cld                         ; Set string instructions to use forward movement

    mov si, boot_init_msg       ; Print boot initialization message
    call print_string_rm

    ; Fast method of enabling A20 may not work on all x86 BIOSes
    ; It is good enough for emulators and most modern BIOSes
    ; See: https://wiki.osdev.org/A20_Line
    cli                         ; Disable interrupts
    in al, 0x92
    or al, 2
    out 0x92, al                ; Enable A20 using Fast Method

    mov si, load_gdt_msg        ; Print loading GDT message
    call print_string_rm

    lgdt [gdtr]                 ; Load our GDT

    mov si, enter_pm_msg        ; Print protected mode message
    call print_string_rm

    mov eax, cr0
    or eax, 1
    mov cr0, eax                ; Set protected mode flag
    jmp CODE32_SEL:start32      ; FAR JMP to set CS

bits 32
start32:
    mov ax, DATA32_SEL          ; Setup the segment registers with data selector
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov esp, 0x9c000            ; Set the stack to grow down from area under
                                ;     EBDA/Video memory

    xor eax, eax                ; Clear EAX for the instructions below
    mov al, [0x450]             ; Byte at address 0x450 = last BIOS column position
    mov [cur_col], eax          ; Copy to current column
    mov al, [0x451]             ; Byte at address 0x451 = last BIOS row position
    mov [cur_row], eax          ; Copy to current row

    mov ax, [0x44a]             ; Word at address 0x44a = # of columns (screen width)
    mov [screen_width], eax     ; Copy to screen width

    mov eax, in_pm_msg          ; Print message we are in protected mode
    call print_string_pm        ; EAX = first parameter

end_loop:
    hlt
    jmp end_loop

; Function: set_cursor
;           set the hardware cursor position based on the
;           current column (cur_col) and current row (cur_row) coordinates
; See:      https://wiki.osdev.org/Text_Mode_Cursor#Moving_the_Cursor_2
;
; Inputs:   None
; Clobbers: EAX, ECX, EDX

set_cursor:
    mov ecx, [cur_row]          ; EAX = cur_row
    imul ecx, [screen_width]    ; ECX = cur_row * screen_width
    add ecx, [cur_col]          ; ECX = cur_row * screen_width + cur_col

    ; Send low byte of cursor position to video card
    mov edx, 0x3d4
    mov al, 0x0f
    out dx, al                  ; Output 0x0f to 0x3d4
    inc edx
    mov al, cl
    out dx, al                  ; Output lower byte of cursor pos to 0x3d5

    ; Send high byte of cursor position to video card
    dec edx
    mov al, 0x0e
    out dx, al                  ; Output 0x0e to 0x3d4
    inc edx
    mov al, ch
    out dx, al                  ; Output higher byte of cursor pos to 0x3d5

    ret

; Function: print_string_pm
;           Display a string to the console on display page 0 in protected mode.
;           Handles carriage return and line feed.
;           Doesn't handle tabs, backspace, wrapping and scrolling.
;
; Inputs:   EAX = Offset of address to print
; Clobbers: EAX, ECX, EDX

print_string_pm:
    push edi
    push esi
    push ebx
    mov esi, eax                ; Set ESI to beginning of string

    ; Assume base of text video memory is ALWAYS 0xb8000
    mov ebx, VIDEO_TEXT_ADDR    ; EBX = beginning of video memory

    mov eax, [cur_row]          ; EAX = cur_row
    mul dword [screen_width]    ; EAX = cur_row * screen_width
    mov edx, eax                ; EDX = copy of offset to beginning of line
    add eax, [cur_col]          ; EAX = cur_row * screen_width + cur_col
    lea edi, [ebx + eax * 2]    ; EDI = memory location of current screen cell

    mov ah, ATTR_WHITE_ON_BLACK ; Set attribute
    jmp .getch
.repeat:
    cmp al, CR                  ; Is the character a carriage return?
    jne .chk_lf                 ;     If not skip and check for line feed
    lea edi, [ebx + edx * 2]    ; Set current video memory pointer to beginning of line
    mov dword [cur_col], 0      ; Set current column to 0
    jmp .getch                  ; Process next character
.chk_lf:
    cmp al, LF                  ; Is the character a line feed?
    jne .write_chr              ;     If not then write character
    mov eax, [screen_width]
    lea edi, [edi + eax * 2]    ; Set current video memory ptr to same pos on next line
    inc dword [cur_row]         ; Set current row to next line
    mov ah, ATTR_WHITE_ON_BLACK ; Reset attribute
    jmp .getch                  ; Process next character

.write_chr:
    inc dword [cur_col]         ; Update current column
    stosw

.getch:
    lodsb                       ; Get character from string
    test al, al                 ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character

.end:
    call set_cursor             ; Update hardware cursor position

    pop ebx
    pop esi
    pop edi
    ret

bits 16

; Function: print_string_rm
;           Display a string to the console on display page 0 in real mode
;
; Inputs:   SI = Offset of address to print
; Clobbers: AX, BX, SI

print_string_rm:
    mov ah, 0x0e                ; BIOS tty Print
    xor bx, bx                  ; Set display page to 0 (BL)
    jmp .getch
.repeat:
    int 0x10                    ; print character
.getch:
    lodsb                       ; Get character from string
    test al,al                  ; Have we reached end of string?
    jnz .repeat                 ;     if not process next character
.end:
    ret

cur_row:      dd 0x00
cur_col:      dd 0x00
screen_width: dd 0x00

boot_init_msg:
    db "Booting sequence initialized...", CR, LF, 0
load_gdt_msg:
    db "Loading GDT...", CR, LF, 0
enter_pm_msg:
    db "Entering 32-bit Protected Mode...", CR, LF, 0
in_pm_msg:
    db "Executing code in protected mode!", CR, LF, 0

align 8
gdt_start:
    dd 0                        ; null descriptor
    dd 0

gdt32_code:
    dw 0FFFFh                   ; limit low
    dw 0                        ; base low
    db 0                        ; base middle
    db 10011010b                ; access
    db 11001111b                ; 32-bit, 4kb granularity, limit 0xffffffff bytes
    db 0                        ; base high

gdt32_data:
    dw 0FFFFh                   ; limit low (Same as code)
    dw 0                        ; base low
    db 0                        ; base middle
    db 10010010b                ; access
    db 11001111b                ; 32-bit, 4kb granularity, limit 0xffffffff bytes
    db 0                        ; base high
end_of_gdt:

gdtr:
    dw end_of_gdt - gdt_start - 1
                                ; limit (Size of GDT - 1)
    dd gdt_start                ; base of GDT

CODE32_SEL equ gdt32_code - gdt_start
DATA32_SEL equ gdt32_data - gdt_start

; Pad boot sector to 510 bytes and add 2 byte boot signature for 512 total bytes
TIMES 510-($-$$) db  0
dw 0xaa55

可以使用以下命令将该代码组装并构建到 1.44MiB 软盘映像中:

nasm -f bin boot.asm -o boot.bin

# Build 1.44MB disk image
dd if=/dev/zero of=disk.img bs=1024 count=1440
dd if=boot.bin of=disk.img conv=notrunc

输出应该类似于:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

程序集 32 位打印显示在 qemu 上运行的代码,无法在真实硬件上运行 的相关文章

  • 是否可以在VM内使用VMX CPU指令?

    VM guest 内部的进程是否有可能使用 VMX AMD V VT x CPU 指令 然后由外部 VMM 处理而不是直接在 CPU 上处理 Edit 假设外部VM使用VMX本身来管理其虚拟客户机 即它在Ring 1中运行 如果可能的话 是
  • 在 x86 程序集中存储大量布尔值的最佳方法是什么?

    最近我一直在处理充满布尔值的大型数组 目前 我将它们存储在 bss部分有一个 space指令 它允许我创建字节数组 但是 由于我只需要存储布尔值 因此我希望从数组中逐位读取和写入数据 目前 我能想到的最好方法是有一个 space指令所需存储
  • 为什么我的代码显示垃圾?

    当我也想打印列表中的每个数字时 我的代码显示垃圾 有什么问题吗 输出应如下所示 给定的数组是 2G 4 PT为什么这是垃圾总数是 7 Code ASSUME CS CODE DS DATA SS STK ORG 0000H DATA SEG
  • 是否可以在Linux上将C转换为asm而不链接libc?

    测试平台为Linux 32位 但也欢迎 Windows 32 位上的某些解决方案 这是一个c代码片段 int a 0 printf d n a 如果我使用 gcc 生成汇编代码 gcc S test c 然后我会得到 movl 0 28 e
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我
  • SIMD 和 VLIW 指令是一样的吗?

    SIMD 单指令多数据 和 VLIW 超长指令字 到底有什么区别 其中一个是另一个的子集吗 或者它们是两个完全不同的东西 完全不相关且正交 一台机器可以有一个或两个 或者两者都没有 SIMD 指令可以作为扩展添加到 VLIW ISA 但 V
  • 避免 gcc 函数序言开销?

    我最近遇到了很多 gcc 在 x86 上生成非常糟糕的代码的函数 它们都符合以下模式 if some condition do something really simple and return else something comple
  • 何时可以重用avx指令中的源寄存器

    在 avx 指令中用作源的寄存器何时可以在指令开始处理后重用 例如 我想使用vgatherdps该指令消耗两个 ymm 寄存器 其中之一是位移索引 我意识到vgatherdps由于数据的局部性较差 因此需要花费大量时间来收集 位移索引寄存器
  • 汇编器8086将32位数字除以16位数字

    我尝试将 32 位数字除以 16 位数字 例如 10000000h 除以 2000h 根据我尝试做的设计除以 右 4 位数字除以除数 然后左 4 位数字除以除数 这是我的代码 DATA num dd 10000000h divisor dw
  • 无法识别的仿真模式:MinGW32 上的 elf_i386

    我正在尝试制作内核 但无法链接C与程序集一起输出 这ld 我收到错误 无法识别的仿真模式 elf i386 我正在使用 Windows 10 专业版以及 MinGW32 和 MSYS 我正在使用的代码 link ld link ld OUT
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits
  • 将 C 代码转换为 x86-64 汇编

    我正在尝试将 C 代码转换为 x86 64 我的目标是反转链表 传入的两个参数是 head ptr 和 offset to 以获取指针字段的地址 即指向列表中下一个节点的指针 据我了解 head ptr是通过rdi寄存器传入的 offset
  • 如何编译一个简单的 multiboot2 裸机可执行文件?

    我想开始写一个操作系统内核 然后 我找到了一个document http nongnu askapache com grub phcoder multiboot pdf引入 multiboot2 规范 有三个示例代码文件 名为boot S
  • 在 Intel x86 架构上使用非 AVX 指令移动 xmm 整数寄存器值

    我有以下问题 需要使用 AVX2 以外的任何工具来解决 我有 3 个值存储在 m128i 变量中 不需要第四个值 需要将这些值移动 4 3 5 我需要两个功能 一个用于按这些值进行右逻辑移位 另一个用于左逻辑移位 有谁知道使用 SSE AV
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • 当 mov 指令导致页面错误并且在 x86 上禁用中断时会发生什么?

    我最近在自定义 Linux 内核 2 6 31 5 x86 驱动程序中遇到一个问题 其中 copy to user 会定期不将任何字节复制到用户空间 它将返回传递给它的字节数 表明它没有复制任何内容 经过代码检查 我们发现代码在调用 cop
  • 学习 (N)ASM 的最佳资源是什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想学习汇编已经有一段时间了 尽管我之前尝试过几次 但我还没有真正能够超越 Hello world 有
  • 64 位 Windows 汇编器

    我想对 64 位 Windows 程序集进行编程 最好使用 NASM 我在 google 上查了一下 但似乎找不到 64 位 Windows 编译器 有些网站提到了ml64 但它似乎不再包含在VC 中 我尝试过 32 位程序集 但显然它在我

随机推荐

  • JSON、REST、SOAP、WSDL 和 SOA:它们如何链接在一起

    目前正在做一些考试 我正在努力解决一些概念 这些确实在我的笔记中 提到 过 但我并不真正理解它们是如何联系在一起的 据我的理解是 SOA 一种使服务消费者 提供者进行通信的解决方案 据我所知 这是其他一切的总称 WSDL 一种描述提供者服务
  • 如何使用 Swift 在 OS X 上读取 Finder 图标(左侧源列表)

    我尝试阅读有关左侧源列表中的查找器中显示的图标的信息 我已经尝试过了NSFileManager有以下选项 NSURLEffectiveIconKey读取的图标与 Finder 中的图标不同 NSURLCustomIconKey 返回零 NS
  • 实体管理器的正确使用方法是什么

    我在 Jersey JAX RS 中有一个 REST 客户端 它接受请求 然后使用 Hibernate 的 JPA 实现从数据库检索数据并返回 JSON 使用共享实体管理器 性能相当不错 但如果有多个请求 我会从 Hibernate 收到异
  • 将 byte[] 转换为 byte[]

    有谁知道一种有效的方法来将 C 中的 2d 数组 非锯齿状 展平为 1d 并再次返回 我知道在后端 C 必须将其作为一维数组保存 如果可能的话 我只想获得后端一维数组的句柄 我想这样做的原因是因为我希望能够在托管代码中将其作为 2d 有时我
  • 是否可以将 docker 端口暴露给特定接口

    我的服务器有两个网络接口 eth0 和 wlan0 一个连接到互联网 另一个连接到内部网络 目前使用 docker compose 将 Docker 容器端口暴露到特定接口的解决方案是使用 version 2 services mosqui
  • 将字符串转换为 SHA1 和 Base64

    我在转换字符串时遇到问题 假设 TestPassword 转换为 SHA1 和 base64 一般来说 根据该网站 http www online convert com result 1f76972748a7d186198171e9a11
  • CXF 的 WS-security(用户名令牌)- 可以加密密码吗?

    我正在尝试与 CXF 的 WS 安全实现 usernametoken 合作 我已经按照上面所说的做了一切http cxf apache org docs ws security html http cxf apache org docs w
  • 允许在加入节点执行多个事件操作

    是否允许在一个连接节点使用多个事件 如下所示 或者是可以用来描述活动流程的虚构令牌 只是在第二个事件出现之前的某一时刻出现并消失了 是否允许在一个连接节点使用多个事件 Yes a JoinNode is a 控制节点同步多个流 是虚构的标记
  • Python。 while 循环中的变量未更新。

    我对编程非常陌生 我在编写一个基本的猜谜游戏时遇到了问题 x是计算机生成的随机数 该程序应该比较 previous guess x 的绝对值和新猜测减去 x 并告诉用户他们的新猜测是否更近或更远 但变量 previous guess 并未使
  • 随机数生成器,如何获得不相同的随机数

    我正在制作一个随机数生成器 但我不想再次生成这些数字 例如 1 2 3 4 是完美的 1 1 2 4 不是我想要的 因为数字重复出现 我看过这里 没有人能回答我正在寻找的问题 按照我的逻辑 这应该可行 但我不知道我做错了什么 我是 pyth
  • 如何在 Excel 工作表内的表对象中插入行?

    我在尝试将行插入现有表对象时遇到困难 这是我的代码片段 string connectionString Provider Microsoft ACE OLEDB 12 0 Data Source C myExcelFile xlsx Ext
  • Jmeter HTTPS代理配置

    我正在尝试使用 jmeter 加载测试 https 网站 我已经使用 jmeter bin 中 proxyserver jks 文件中的 keytool 安装了客户端证书 pfx 我还使用jmeter手册配置了jmeter代理和firefo
  • 如何将 Bamboo 变量从 Bamboo 脚本发送到 docker 容器?

    我正在为bamboo 使用 Docker 插件 我需要在 docker 容器中执行一个脚本 sh 脚本包含 echo ini source path bamboo ini source path 如果我将此行直接放入容器命令中 则 bamb
  • 删除或重置 Cookie

    我正在设置一个cookieRequest Cookies TemplateName value在我的申请的其中一页 第 3 页 上 现在我可以从第 3 页导航到第 4 页和第 2 页 并保留 cookie 的值 但是现在当我注销并再次登录时
  • RxJS 更新,类型“typeof Observable”上不存在属性“merge”

    我更新了我的材质角度项目 以在表中包含可扩展的详细信息行 为此 我需要升级到 rsjx 6 现在我收到以下错误 我对角度完全陌生 所以不幸的是我不知道如何解决这个问题 Property merge does not exist on typ
  • 发送带有授权标头的 axios get 请求

    我尝试使用 vue js 发送 axios get 请求 当不需要发送标头时它工作得很好 但是 当需要发送授权 jwt 时 我收到 CORS 错误 对预检请求的响应未通过访问控制检查 请求的资源上不存在 Access Control All
  • 通过地理位置获取用户的状态

    获取美国用户所在州的最有效方法是什么 HTML5 地理定位是否是一种无需涉及谷歌地图的选项 这里有几个 JavaScript 和 JSON 的例子 在jQuery http jquery com 使用IP查找方法 借助IPinfoDB ht
  • UITableView - 使用 Swift 注册类

    其他人在使用时遇到问题吗tableView registerClass方法与斯威夫特 它不再为我提供代码补全 如果手动键入 我也不能使用它 但它仍然在标题中 它对我来说非常有效 self tableView register UITable
  • CGAL:继承和内核

    CGAL问题 我正在尝试向点类添加一个属性 我想第一步是继承一个内核并用我自己的从 CGAL 继承的点类替换点类 但只是想迈出这小小的第一步 我就遇到了麻烦 编辑 根据下面的评论 我将继承更改为手册中描述的方式 下面的代码给出了以下编译错误
  • 程序集 32 位打印显示在 qemu 上运行的代码,无法在真实硬件上运行

    我已经用 x86 汇编语言编写了一小段在裸硬件上运行的代码 此时 它已启用受保护的 32 位模式 然而 我遇到了与屏幕打印有关的问题 我读到 要在不中断的情况下执行此操作 可以将字符加载到特殊的内存区域 即 RAM 地址 0xb8000 知