小编Pet*_*des的帖子

为什么我的汇编子例程被调用,即使我没有在引导加载程序的 _start 中调用它

我目前正在开发一个 BIOS 引导加载程序,我对汇编比较陌生,我一直在阅读它,我了解它是如何工作的,但有一些事情我不明白,涉及我的汇编代码的执行顺序。

所以基本上我的子例程 _print 是如何被调用的,即使我没有调用它。其次,如果BIOS幻数一直在文件末尾,即使我没有到达,它是如何分配的。

我将不胜感激任何帮助,谢谢。

[ORG 0000:7C00]

global _start 

_print:
    mov ah, 0x0e 
    mov al, '['
    int 0x10
    mov al, '+'
    int 0x10
    mov al, '['
    int 0x10
    ret

_start:
    jmp $

times 510 - ($-$$) db 0
dw 0xAA55
Run Code Online (Sandbox Code Playgroud)

assembly nasm bootloader x86-16

0
推荐指数
1
解决办法
66
查看次数

程序如何知道在堆栈上为局部变量分配多少空间?

在这个简单的函数中,为局部变量分配了空间。然后,变量被初始化并被printf调用以输出它们。

000000000040056a <func>:
  40056a:       55                      push   rbp                     ; function prologue
  40056b:       48 89 e5                mov    rbp,rsp                 ; function prologue
  40056e:       48 83 ec 10             sub    rsp,0x10                ; deallocating space for local variables
  400572:       8b 4d fc                mov    ecx,DWORD PTR [rbp-0x4] ; variable initialization
  400575:       8b 55 f8                mov    edx,DWORD PTR [rbp-0x8] ; variable initialization
  400578:       8b 45 f4                mov    eax,DWORD PTR [rbp-0xc] ; variable initialization
  40057b:       89 c6                   mov    esi,eax                 ; string stuff
  40057d:       bf 34 06 40 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly x86-64 stack-frame

0
推荐指数
1
解决办法
843
查看次数

C 中的内联汇编

我正在用 c 语言编写一个国际象棋引擎,速度至关重要。国际象棋引擎基于 unsigned long long,我将其表示为 u64,并且它严重依赖于最低有效位扫描。到目前为止,我一直在使用 gcc 函数 __builtin_ctzll ,它做得很好。然而,我使用 gcc -S -O2 为这个独立函数生成了汇编代码。它给了我以下内容:

xorl     %eax, %eax
rep bsfq %rdi, %rax
cltq
ret
Run Code Online (Sandbox Code Playgroud)

然而经过一番调查似乎代码

rep bsfq %rdi, %rax
ret
Run Code Online (Sandbox Code Playgroud)

在我的国际象棋程序中做了完全相同的事情。然而现在速度慢了约 20%。它应该更快,因为它的指令更少。然而,原始的 __builtin_ctzll 内联在我的 C 代码中。这是我的自定义汇编代码运行速度比原始代码慢的原因吗?因为当我声明函数 ctzll 时,我当然不能在 c 中内联声明它,除非我有定义(不在汇编代码中)。

是否有另一种方法来优化汇编指令,或者我应该尝试直接在 c 中内联 asm 的新汇编代码?

c assembly gcc x86-64 micro-optimization

0
推荐指数
1
解决办法
374
查看次数

PSHUFD SHUFPD 有什么区别

我阅读了这两个操作的手册描述,但还不明白其中的区别。有人可以举例说明 shufpd 与 pshufd 的比较吗?

assembly sse

0
推荐指数
1
解决办法
713
查看次数

在std::atomic&lt;T&gt;::exchange的例子中,为什么次数不是25?

我谈到的例子是cppreference.com 上的这个例子。代码片段粘贴在下面。

int main(){
    const std::size_t ThreadNumber = 5;
    const int Sum = 5;
    std::atomic<int> atom{0};
    std::atomic<int> counter{0};
 
    // lambda as thread proc
    auto lambda = [&](const int id){
        for (int next = 0; next < Sum;){
            // each thread is writing a value from its own knowledge
            const int current = atom.exchange(next);
            counter++;
            // sync writing to prevent from interrupting by other threads
            std::osyncstream(std::cout)
                << '#' << id << " (" << std::this_thread::get_id()
                << ") wrote " …
Run Code Online (Sandbox Code Playgroud)

c++ atomic stdatomic

0
推荐指数
1
解决办法
93
查看次数

您能给我一些关于如何有效设计汇编语言程序的指导吗?

我是一名大学计算机科学学生,我应该为考试开发一个 MIPS 汇编语言程序,但我确实很难设计它,特别是在分配寄存器、遵循调用约定、将寄存器保存在堆栈...这一切似乎很快变得非常混乱和难以承受,我迷失了方向!

至少在概念上,我不难找出解决特定问题的算法。它更多地与项目的大局、整体结构和设计有关。

鉴于此,您能否指出一种模式,提供一些技巧或最佳实践,以在实际编写代码之前对所有内容进行排序,以便我不会在这个过程中迷失自己?

software-design mips mips32

0
推荐指数
1
解决办法
264
查看次数

为什么重定位表的所有元素都有一个额外的偏移量?

问题是将可移植可执行映像加载到随机地址。

我们以kernel32.dll为例,加载于0x75A00000。

我可以看到在图像的偏移 0x10e15 处有一条汇编指令,这取决于图像所在的位置。

地址:75A10E13 字节:8B 35 18 03 AE 75 命令:MOV ESI,DWORD PTR DS:[75AE0318]

事实证明,通过启动可执行文件,我们必须告诉系统我们需要重定位到这个地址。

系统查看可执行文件中的重定位表,并看到以下内容: 基本重定位表

为了获取要移动的第一个元素的绝对地址,我执行以下操作:将虚拟地址添加到图像的地址,然后将块的第一个元素添加到结果数字。

0x75A00000 + 0x10000 + 0x3E15 = 75A10E15

这是一个很好的数字,但总是比我预期多 0x3000。我只需减去 0x3000 就可以了。请帮我找到答案,x86 的 0x3000 从哪里来?

windows dll x86 relocation portable-executable

0
推荐指数
1
解决办法
220
查看次数

如果 C 和 C++ 的 double(和 float)是 IEEE 754-1985,那么整数表示形式和 Infinity、-0、NaN 等是否都未使用?

看起来JavaScript的number类型与C和C++的double类型完全相同,并且都是IEEE 754-1985

JavaScript 可以使用 IEEE 754 作为整数,但是当数字变大或进行算术计算(例如除以10或 by )时3,它似乎可以切换到浮点模式。现在,C 和 C++ 仅使用 IEEE 754 作为double,因此仅使用浮点部分,而不使用“整数”部分。因此,C 和 C++ 是否未使用整数表示形式?

(C 未使用NaN, Infinite, -Infinite,-0因为我记得在 C 中从未使用过它们)。

c c++ floating-point double ieee-754

0
推荐指数
1
解决办法
477
查看次数

为什么内联汇编不需要像 .data 或 .text 这样的节指令

作为一个新手,我正在遵循教程。一种是在 VS 2022 的内联汇编中将字符串中的所有字符大写:

int main()
{
    char mystr[] = "Hello World:";

    _asm
    {
        mov ecx, length mystr
    my: cmp [mystr + ecx], 'a';
        jl nocap;
        cmp [mystr + ecx], 'z';
        ja nocap;
        sub [mystr + ecx], 32;

    nocap:
    loop my
    }

    std::cout << mystr;
Run Code Online (Sandbox Code Playgroud)

我的问题是:为什么这个程序集不需要节,例如 .data、.text 或 _start:示例中可能混合了 x86 asm 和 Linux asm。

x86 assembly inline-assembly

0
推荐指数
1
解决办法
432
查看次数

装配无限数量

我觉得这个问题可能有点蠢。。

由于我们存储位来指示数字,并且由于我们拥有整个 RAM,因此我们应该能够拥有一个无限大小(实际上是自定义大小)的数字,该数字可以占用整个 RAM(或其指定部分) )。

正确的?

例如,如果我们这样做:

mov ax, 0xFFFF
add ax, 1
jc custom_function ; if I remember correctly jc checks the carry flag
Run Code Online (Sandbox Code Playgroud)

custom_function 是一个标签/函数,它具有一种算法来设置下一个位以创建无限大小的数字。

问题

  1. 这可能吗?如果不是无限大小的数字,则指定自定义(比默认值更长或更短)

  2. 我怀疑,如果可能的话,它的性能会很差(即使数量更短)。你怎么认为?

  3. 你认为拥有这样的东西会很好吗?(也许在内存有限的旧系统或嵌入式系统中这会更有效?)

embedded binary assembly numbers bigint

0
推荐指数
1
解决办法
133
查看次数