如何获取 RAM 大小、引导加载程序

2024-03-22

我想问如何在引导加载程序中获取总 RAM 大小和可用 RAM 大小。截至目前,我知道如何获得较低的内存。但由于某种原因我无法将其打印到屏幕上,因为它保存在斧头寄存器中。这是我到目前为止所拥有的:

[BITS 16] ; BootLoader always starts 16 BIT Moded

    jmp main_bootloader ; Jump to Main Bootloader

     ;************** INITALIZED VARIABLES *********************;
      string db 'BoneOS Loading . . .', 0x0
      string2 db 'Starting of 16Bit Bootloader' , 0x0
      press_to_cont db 'Press any key to continue . . .' , 0x0
      carry_flag_err db ' CARRY FLAG HAS BEEN SET! ERROR ' , 0x0
      magic_number equ 0x534D4150
      limit dw 0
      base  dw 0
      low_memory dd 0
      answer resb 64
     ;*********************************************************;  

     ;******************** GDTs *****************************;


         null_descriptor :
            dd 0                ; null descriptor--just fill 8 bytes with zero
            dd 0 

        ; Notice that each descriptor is exactally 8 bytes in size. THIS IS IMPORTANT.
        ; Because of this, the code descriptor has offset 0x8.

         code_descriptor:           ; code descriptor. Right after null descriptor
            dw 0FFFFh           ; limit low
            dw 0                ; base low
            db 0                ; base middle
            db 10011010b            ; access
            db 11001111b            ; granularity
            db 0                ; base high

        ; Because each descriptor is 8 bytes in size, the Data descritpor is at offset 0x10 from
        ; the beginning of the GDT, or 16 (decimal) bytes from start.

         data_descriptor:           ; data descriptor
            dw 0FFFFh           ; limit low (Same as code)
            dw 0                ; base low
            db 0                ; base middle
            db 10010010b            ; access
            db 11001111b            ; granularity
            db 0                ; base high

        end_of_gdt: 
            toc: 
                dw end_of_gdt - null_descriptor - 1     ; limit (Size of GDT)
                dd null_descriptor          ; base of GDT   

        load_gdt:
            lgdt [toc]

        .done:
            ret


     ;*********************************************************;

     ;*************** LABELS FOR MAIN **************************;
        print_char_boot:
            mov ah, 0Eh ; Code For BIOS To Print Char 0Eh

        .repeat:
            lodsb ; Load Byte From SI Register
            cmp al, 0 ; Compare AL With 0 If so Done
            je .done 
            int 10h ; Call Interupt. Checks AH Register for code 0EH = Print char
            jmp .repeat ; Loop Back

        .done:
            ret ; Return to previous code


        print_new_line:
               mov al, 0    ; null terminator '\0' 
               ;Adds a newline break '\n'
               mov ah, 0x0E
               mov al, 0x0D
               int 0x10
               mov al, 0x0A 
               int 0x10
               ret

        get_pressed_key:
            mov ah, 0
            int 0x16  ;BIOS Call. Key goes to al register
            ret 
        GET_RAM_SIZE:

        reboot:
            mov si, press_to_cont
            call print_char_boot
            call get_pressed_key ; Gets Pressed Key

            int 19h ;Reboot
            ret

        enable_A20: ; Enabling A20 Line For Full Memory
            cli ; Stop Interupts before doing so

            call    a20wait ; a20wait call
            mov     al,0xAD ; Send 0xAD Command to al register
            out     0x64,al ; Send command 0xad (disable keyboard).

            call    a20wait ; When controller ready for command
            mov     al,0xD0 ; Send 0xD0 Command to al register
            out     0x64,al ; Send command 0xd0 (read from input)

            call    a20wait2 ; When controller ready for command
            in      al,0x60 ; Read input from keyboard
            push    eax ; Save Input by pushing to stack

            call    a20wait ; When controller ready for command
            mov     al,0xD1 ; mov 0xD1 Command to al register
            out     0x64,al ; Set command 0xd1 (write to output)

            call    a20wait ; When controller ready for command
            pop     eax ; Pop Input from Keyboard
            or      al,2 ; Mov 0xD3 to al register
            out     0x60,al ; Set Command 0xD3

            call    a20wait ; When controller ready for command
            mov     al,0xAE ; Mov Command 0xAE To al register
            out     0x64,al ; Write command 0xae (enable keyboard)

            call    a20wait ; When controller ready for command
            sti ; Enable Interrupts after enabling A20 Line
            ret

                a20wait:
                    in      al,0x64 ; input from 0x64 port, goes to al register
                    test    al,2 ; compares al register with 2
                    jnz     a20wait ; If it is zero loop again
                    ret


                a20wait2:
                    in      al,0x64 ; input from 0x64 port, goes to al register
                    test    al,1 ; compares al register with 2
                    jz      a20wait2 ; If it is zero loop again
                    ret 


            get_lower_memory:
                clc ; Clears Carry Flag
                int 0x12 ; BIOS Call Request Lower Memory Size in KB
                jc .err ; If Carry Flag Has Been Set , the system its running on dosent support this
                jmp .done ; If Sucessfull ax register contains contiguous low memory in KB

            .err:
                times 5 call print_new_line ; Prints New Line
                mov si, carry_flag_err
                call print_char_boot 
                jmp .repeat

            .done:
            ret

        .repeat:
            jmp .repeat





;**************************************************************;


;*******************'MAIN' BOOTLOADER FUNCTION ****************;
main_bootloader:
    xor ax, ax
    mov ss, ax
    mov sp, 4096

    mov ax, 07C0h       ; Set data segment to where we're loaded
    mov ds, ax

    mov si, string ; si register usefull for lodsb command
    call print_char_boot ; Call print_char_boot label below
    call print_new_line ; Prints New Line
    mov si, string2
    call print_char_boot 
    times 2 call print_new_line
    ; Enable A20 Line
    call enable_A20

    call get_lower_memory ; Get Low Memory


    mov si,ax
    call print_char_boot 
    times 5 call print_new_line

    call reboot ; Reboot

    ;call null_descriptor


    jmp $ ; Infinite Loop 
    ;Bootloader gets infinite loop 
    ;Incase No Infinite Loop in Kernel

;****************************************************************;  


;************************* BOOTLOADER REQUIREMENTS **************;  
times 510 - ($ - $$) db 0 ; Has to be 512 bytes .. Repeats 510 byes to make it so
dw 0xAA55 ; BootLoader Sig. To Validate this is a bootloader
;

****************************************************************;

正如你在我的主页上看到的,我是call get_lower_memory ; Get Low Memory,获取低内存。但我已经测试了打印斧头寄存器,但屏幕上没有显示任何内容。而且我也不知道如何在系统中获取总的可用内存。非常感谢您的帮助!


尽管您的帖子正文中提出的问题更多的是关于打印寄存器的值,而不是检测系统可用的内存,但我将忠于标题问题,并提供一个如何检测的示例系统内存映射。

作为奖励,提供了一个将 32 位无符号整数显示为十六进制数字的函数,以及一个非常原始的函数print支持占位符。


Detecting memory is not an easy task, it requires full knowledge of the hardware installed1 and cannot be done without it (see Detecting memory http://wiki.osdev.org/Detecting_Memory_(x86)#Manual_Probing on OSDev).
As a simple example think of an aliased memory https://en.wikipedia.org/wiki/Aliasing_(computing)#Hardware_aliasing, the software cannot detect that without any involved and slow method.

承认与 BIOS 的合作是强制性的,我们可以看到 16 位实模式引导加载程序可以使用哪些服务。
上面提到的 OSDev 页面关于检测记忆 http://wiki.osdev.org/Detecting_Memory_(x86)已经有专门用于上述目的的服务列表,可供参考。

我们将重点关注整数 15/AX=E820h http://www.ctyme.com/intr/rb-1741.htm服务。
它的用途是返回内存范围及其描述的列表。
每次调用都会返回下一个描述符,使用ebx跟踪进展情况。登记册ebx应被视为不透明值。
尽管描述中Ralf 的 Brown 中断列表,描述符可以是 24 字节长,因此最好使用该长度并最终检查返回的值ecx区分 20/24 字节描述符。


Once we have the list of descriptors they can be used by the routine dictated to allocating memory2.
It is worth nothing tow things:

  1. 描述符是not订购了。一些有缺陷的 BIOS 可能会返回重叠的区域(在这种情况下做出最保守的选择)。

  2. 可能有gaps即使描述符已排序。不报告没有内存映射的范围,这是标准孔的情况(范围从 0a0000h 到 0fffffh)。

  3. 不过,会报告 BIOS 明确保留的区域(例如从 0f0000h 到 0fffffh 的影子区域)。

In the example below the descriptors are printed on the screen along with the total amount of non reserved memory3.

顺便说一句,您可以使用itoa16打印 32 位值的函数EAX,假设您更改了字符在屏幕上打印的方式。

BITS 16

;Set CS to a known value
;This makes the offsets in memory and in source match 
;(e.g. __START__ is at offset 5h in the binary image and at addres 7c0h:0005h)

jmp 7c0h:__START__

__START__:
 ;Set all the segments to CS 
 mov ax, cs
 mov ds, ax
 mov es, ax
 mov ss, ax
 xor sp, sp

 ;Clear the screen
 mov ax, 03h
 int 10h

 ;FS will be used to write into the text buffer
 push 0b800h
 pop fs

 ;SI is the pointer in the text buffer 
 xor si, si 

 ;These are for the INT 15 service
 mov di, baseAddress                    ;Offset in ES where to save the result
 xor ebx, ebx                           ;Start from beginning
 mov ecx, 18h                           ;Length of the output buffer (One descriptor at a time)

 ;EBP will count the available memory 
 xor ebp, ebp 

_get_memory_range:
 ;Set up the rest of the registers for INT 15 
 mov eax, 0e820h 
 mov edx, 534D4150h
 int 15h
 jc _error 

 ;Has somethig been returned actually?
 test ecx, ecx
 jz _next_memory_range

 ;Add length (just the lower 32 bits) to EBP if type = 1 or 3 
 mov eax, DWORD [length]

 ;Avoid a branch (just for the sake of less typing)

 mov edx, DWORD [type]         ;EDX = 1        | 2        | 3        | 4   (1 and 3 are available memory)
 and dx, 01h                   ;EDX = 1        | 0        | 1        | 0 
 dec edx                       ;EDX = 0        | ffffffff | 0        | ffffffff 
 not edx                       ;EDX = ffffffff | 0        | ffffffff | 0 
 and eax, edx                  ;EAX = length   | 0        | length   | 0 

 add ebp, eax

 ;Show current memory descriptor 
 call show_memory_range

_next_memory_range:
 test ebx, ebx 
 jnz _get_memory_range

 ;Print empty line
 push WORD strNL 
 call print 

 ;Print total memory available 
 push ebp 
 push WORD strTotal
 call print 

 cli
 hlt

_error:
 ;Print error
 push WORD strError
 call print

 cli 
 hlt


 ;Memory descriptor returned by INT 15 
 baseAddress dq 0
 length      dq 0
 type        dd 0
 extAttr     dd 0

 ;This function just show the string strFormat with the appropriate values 
 ;taken from the mem descriptor 
 show_memory_range:
  push bp
  mov bp, sp

  ;Extend SP into ESP so we can use ESP in memory operanda (SP is not valid in any addressing mode)
  movzx esp, sp 

  ;Last percent
  push DWORD [type]

  ;Last percents pair
  push DWORD [length]
  push DWORD [length + 04h]

  ;Add baseAddress and length (64 bit addition)
  push DWORD [baseAddress]
  mov eax, DWORD [length]
  add DWORD [esp], eax               ;Add (lower DWORD)
  push DWORD [baseAddress + 04h]
  mov eax, DWORD [length + 04h]
  adc DWORD [esp], 0                 ;Add with carry (higher DWORD)

  ;First percents pair
  push DWORD [baseAddress]
  push DWORD [baseAddress + 04h]

  push WORD strFormat
  call print

  mov sp, bp                         ;print is a mixed stdcall/cdecl, remove the arguments

  pop bp
  ret

 ;Strings, here % denote a 32 bit argument printed as hex 
 strFormat db "%% - %% (%%) - %", 0
 strError  db "Som'thing is wrong :(", 0
 strTotal  db "Total amount of memory: %", 0 
 ;This is tricky, see below 
 strNL     db 0

 ;Show a 32 bit hex number
 itoa16:
  push cx
  push ebx

  mov cl, 28d

 .digits:
   mov ebx, eax
   shr ebx, cl
   and bx, 0fh                     ;Get current nibble

   ;Translate nibble (digit to digital)
   mov bl, BYTE [bx + hexDigits]

   ;Show it 
   mov bh, 0ch
   mov WORD [fs:si], bx
   add si, 02h   

   sub cl, 04h
  jnc .digits

  pop ebx
  pop cx
  ret

  hexDigits db "0123456789abcdef"

  ;This function is a primitive printf, where the only format is % to show a 32 bit 
  ;hex number 
  ;The "cursor" is kept by SI.
  ;SI is always aligned to lines, so 1) never print anything bigger than 80 chars
  ;2) successive calls automatically print into their own lines 
  ;3) SI is assumed at the beginning of a line 

  ;Args
  ;Format
  print:
   push bp
   mov bp, sp

   push di
   push cx

   mov di, WORD [bp+04h]      ;String 
   mov cx, 80*2               ;How much to add to SI to reach the next line 

   add bp, 06h                ;Pointer to var arg 

  .scan:

    ;Read cur char 
    mov al, [di]
    inc di

    ;Format?
    cmp al, '%'
    jne .print

    ;Get current arg and advance index 
    mov eax, DWORD [bp]
    add bp, 04h
    ;Show the number 
    call itoa16

    ;We printed 8 chars (16 bytes) 
    sub cx, 10h

   jmp .scan    

  .print:
    ;End of string?
    test al, al
    je .end

    ;Normal char, print it 
    mov ah, 0ch
    mov WORD [fs:si], ax
    add si, 02h
    sub cx, 02h

   jmp .scan   


  .end:
   add si, cx

   pop cx
   pop di

   pop bp
   ret 02h

   ;Signature
   TIMES 510 - ($-$$) db 0 
   dw 0aa55h

在 64MiB Bochs 仿真机器中,结果是

格式在哪里开始 - 结束(大小) - 类型.

使用我们得到的图片

                                                         Map

计算得出的内存总量为 66.711.552 字节或 64 MiB - 1 KiB (EBDA) - 96 KiB(阴影区域) - 288 KiB(标准孔)。
ACPI 表被视为可用,因为它们是可回收的。


1 Particularly of what was the part of the north bridge, now iMC, dedicated to handling the DRAM. Information about installed modules (Mostly DIMM and mobile variants) can be retrieved through SPD https://en.wikipedia.org/wiki/Serial_presence_detect using either a SMBus http://smbus.org/specs/smbus20.pdf or I2C https://en.wikipedia.org/wiki/I%C2%B2C controller.
The BIOS then consider the enabled memory mapped devices and the bus topology (along with its routing and bridging information) and exposes all this through the the SMBios specification http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf.

2 Since it will use some sort of range descriptors anyway, eventually a format conversion is performed.

3 This count includes the newly type 5 (Bad memory) range.

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

如何获取 RAM 大小、引导加载程序 的相关文章

  • MASM 字符串反转

    好吧 我正在讨论这个问题 可能是一个非常复杂的解决方案 但这是我脑海中浮现的第一件事 我需要编写一个汇编语言程序来反转 源 字符串 而不使用 目标 字符串 临时变量 这是我的尝试 INCLUDE Irvine32 inc data sour
  • 如何在 Ubuntu 14.04 LTS 中安装 ia32-libs (Trusty Tahr)

    我昨天安装了 Ubuntu 14 04 Trusty Tahr 一切看起来都还好 但是当我尝试编译一些C代码时 我遇到了以下错误 该错误似乎是由于操作系统缺乏 32 位架构支持造成的 错误输出如下 usr bin ld i386 archi
  • C/C++ 中的简单“Hello World”内联汇编语言程序

    我使用 devcpp 和 borland c 编译器 asm mov ax 4 I O Func mov bx 1 Output func mov cx name address of the string mov dx 6 length
  • 为什么当设置为 TLS 选择器时,ES 和 DS 在 64 位内核上最终会归零?

    下面的 32 位程序调用set thread area 2 http linux die net man 2 set thread area在 GDT 中创建一个条目 该条目旨在用于 TLS 通常将结果选择器放入FS or GS并成功使用
  • 装配中出现奇怪的字符?

    我写了以下代码 386 model small stack 100h data text db Paper 0 code start lea dx text mov ah 9h int 21h mov ah 4ch int 21h end
  • 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?

    我正在使用实现一个功能cpuid根据 AMD64 SysV ABI 进行组装 我需要在函数本身中使用 2 个临时寄存器 第一个用于累积返回值 第二个用作计数器 我的功能目前如下所示 zero argument function some c
  • 为什么这个“std::atomic_thread_fence”起作用

    首先我想谈一下我对此的一些理解 如有错误请指正 a MFENCE在x86中可以保证全屏障 顺序一致性可防止 STORE STORE STORE LOAD LOAD STORE 和 LOAD LOAD 重新排序 这是根据维基百科 https
  • 一条指令可以同时处于两种寻址模式吗?

    我在书中读到了以下内容从头开始编程 处理器有多种不同的访问数据的方式 称为 寻址模式 最简单的模式是立即模式 其中 要访问的数据嵌入在指令本身中 例如 如果我们想将寄存器初始化为 0 而不是给出 计算机要从中读取 0 的地址 我们将指定立即
  • x86-64 上这个语句有什么问题?

    该函数的目的是获取堆栈的起始地址 unsigned long find start void asm movq rsp eax 当我编译它时 出现错误 Error suffix or operands invalid for movq mo
  • 什么时候汇编比C更快? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的
  • CALL指令是否总是将EIP指向的地址压入堆栈?

    x86架构中函数调用时是否存在返回地址不入栈的情况 No CALL根据定义 将在跳转到目标地址之前将返回地址压入堆栈 该返回地址是EIP or RIP sizeof call instruction 通常为 5 个字节 英特尔 64 和 I
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 从汇编程序获取命令行参数

    通读 专业汇编语言书籍 似乎它提供了用于读取命令行参数的错误代码 我纠正了一点 现在它从段错误变成了读取参数计数 然后是段错误 这是完整的代码 data output1 asciz There are d params n output2
  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • 在 x86-64 CPU 上通过交叉修改代码重现意外行为

    Question 对于可能在 x86 或 x86 x64 系统上触发意外行为的交叉修改代码有哪些想法 在这些系统中 交叉修改代码中的所有操作均已正确完成 但在执行处理器之前执行序列化指令除外修改代码 如下所述 我有一个 Core 2 Duo
  • 汇编8086监听键盘中断

    我有与此完全相同的问题 边画边听键盘 https stackoverflow com questions 13970325 8086 listen to keyboard while drawing 但第一个答案 接受的答案 只听键盘一次
  • 为什么 GCC 不将 a*a*a*a*a*a 优化为 (a*a*a)*(a*a*a)?

    我正在对科学应用程序进行一些数值优化 我注意到的一件事是 GCC 会优化调用pow a 2 通过将其编译成a a 但是调用pow a 6 没有优化 实际会调用库函数pow 这大大降低了性能 相比之下 英特尔 C 编译器 http en wi
  • 用于预乘 ARGB 的 SSE alpha 混合

    我正在尝试编写一个支持 SSE 的 alpha 合成器 这就是我想出的 首先 混合两个 4 像素向量的代码 alpha blend two 128 bit 16 byte SSE vectors containing 4 pre multi
  • Intel 64 和 IA-32 上的 MESI 有何意义

    MESI 的要点是保留共享内存系统的概念 然而 对于存储缓冲区 事情就变得复杂了 一旦数据到达 MESI 实现的缓存 下游内存就会保持一致 然而 在此之前 每个核心可能对内存位置 X 中的内容存在分歧 具体取决于每个核心的本地存储缓冲区中的
  • 寄存器寻址模式与直接寻址模式

    我在试卷中遇到过这个问题 它指出 哪种给定的寻址模式更快 为什么 寄存器寻址方式 直接寻址方式 现在根据我的说法 寄存器寻址模式应该更快 因为寄存器是计算机中最快的存储位置 这是正确答案吗 请帮忙 谢谢 两种寻址模式之间的区别是 地址的来源

随机推荐

  • 解析多部分表单数据

    我正在尝试组合一个 HTML POST 表单 该表单具有两个字段 文件上传和文本字段 由于表单具有用于文件上传的 multipart form data 类型 因此我无法通过正常的 PHP POST 变量获取文本字段 那么如何使用 PHP
  • ASP.NET 中的静态对象浪费内存?

    前几天我只是想知道这个问题 我不太确定 ASPX 如何管理垃圾处理 但据我所知 完成加载 不会删除静态内存值或在页面重新加载后 至少就 C 而言 静态意味着内存分配会跟随您的程序 直到程序本身关闭 ASPX 中也是这样吗 如果我有一个静态值
  • 我们可以在 C# 项目中使用 COM 对象吗?

    我按照教程制作了一个 C COM 对象 http www codeproject com Articles 18939 C Com http www codeproject com Articles 18939 C Com 现在我想在 C
  • VB.NET 中的 UploadString(Post 方法)不起作用

    我正在尝试将简单数据发布到某个站点 在本例中发布到本地服务器上的 php 文件 我的 VB NET 代码 Dim W As New Net WebClient Dim A As String W Encoding System Text E
  • Google 如何确定将页面索引为讨论页面? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在自己建立一个问答网站 我想让这个网站被Google索引为问答网站或论坛 可以在使用Google中的 讨论 时检索到 根据我的个人经验 当我想获得
  • pymongo:使用 MongoReplicaSetClient 的优点?

    看来两者Mongo客户端 http api mongodb org python current api pymongo mongo client html and MongoReplicaSet客户端 http api mongodb o
  • IOS:停止 NSTimer [重复]

    这个问题在这里已经有答案了 可能的重复 NSTimer 不会停止 https stackoverflow com questions 1031554 nstimer doesnt stop 我有这个代码 NSTimer scheduledT
  • TensorFlow中矩阵乘法函数的使用

    我对这个函数的使用有点困惑tf matmul 在 TensorFlow 中 不过 我的问题可能更多是关于深度学习的理论 假设你有一个输入 X 和权重矩阵 W 假设零偏差 我想将 WX 计算为输出 可以通过以下方式完成tf matmul W
  • 找不到适用于 jdbc:mysql/localhost:3306/world 的驱动程序

    我是这个领域编程的新手 我在驱动程序方面遇到了一些问题 有点 当我直接与客户端一起使用时 MySql 工作正常 问题是我无法将 tomcat 与 MySql 连接 我将所有驱动程序放在 WEB INF lib 中 使用mysql 5 7 t
  • Word 文档的 XML/XSD 验证

    我有一份将不断更新的文档 由文本和表格组成 这些表有两行 第一行包含数字范围 第二行包含单个数字 我想检查第 2 行中的数字是否在第 1 行给出的范围内 我想使用 XML 和 XSD 来执行此操作 我最初的想法是从单词 doc 创建一个 X
  • python-docx 从下拉列表中获取信息(在表中)

    我有一个包含多个表的 docx 文件 我想从列表中的表中获取所有信息 该列表称为 alletabellen 通过下面的脚本 我收到了表格中几乎所有的信息 除了下拉列表中的某些变量的值 在某些表格单元格中 这些单元格的值在我的列表中保持为空
  • 你能避免与 Promise 完全嵌套吗? [复制]

    这个问题在这里已经有答案了 据我了解 Promise 的主要卖点之一是能够编写扁平代码 或者 比回调地狱更扁平 尽管在很多情况下我们似乎需要嵌套 Promise 才能使用闭包 例如 来自q https www npmjs org packa
  • 使用 selenium webdriver 从 Jquery、日期选择器中选择日期

    前往Jquery官网https jqueryui com datepicker https jqueryui com datepicker 不允许单击输入文本 即使它具有唯一的 id datepicker 获取错误元素未找到异常 但当我通过
  • Netbeans:需要在类路径中包含第 3 方目录

    我们有一个在 NetBeans 中开发的应用程序 基于 NetBeans 平台 我们有一个运行时依赖的第 3 方程序 更具体地说 是其他程序 lib 文件夹中的 jar 我们应该如何将其他程序的 jar 包含在我们的类路径中 其他程序制造商
  • Angular ng-submit 未触发所需的控制器方法[重复]

    这个问题在这里已经有答案了 在 Angular 1 4 7 中 我试图在这个 plunk 中实现一个基本的登录表单http plnkr co edit xQEN1ZNN5ZEw1CSwNw97 p preview http plnkr co
  • Javafx:同时多个密钥侦听器

    我正在尝试在 Javafx 中重新创建 Pong 游戏 但我遇到了平台移动的问题 我使用 keylisteners 和 switch 语句来上下移动平台 左边的一个带有 W 和 S 右边的一个带有 Up 和 Down 当我单独按下它们时效果
  • 使用非唯一索引列日期提取 Dask 数据框中的最新值

    我对 pandas 数据帧非常熟悉 但对 Dask 还很陌生 所以我仍在尝试并行化我的代码 我已经使用 pandas 和 pandarallel 获得了我想要的结果 所以我想知道是否可以使用 Dask 扩大任务规模或以某种方式加快速度 假设
  • 如何使用 Windows 中的 log4net xml 配置器使用文件夹位置指定日志文件路径?

    在我的 app config 中我放入
  • ASP.NET MVC:从视图调用控制器方法

    我正在 ASP NET MVC 视图上实现分页 并且我想从视图调用控制器中的方法 视图中的代码 a href gt 控制器方法 public string NextPage string currentPage return int Par
  • 如何获取 RAM 大小、引导加载程序

    我想问如何在引导加载程序中获取总 RAM 大小和可用 RAM 大小 截至目前 我知道如何获得较低的内存 但由于某种原因我无法将其打印到屏幕上 因为它保存在斧头寄存器中 这是我到目前为止所拥有的 BITS 16 BootLoader alwa