Tag: 汇编

什么确保操作数的读/写在扩展ASM的期望时间发生?

根据GCC的扩展ASM和汇编程序模板 ,为了使指令连续,它们必须位于同一个ASM块中。 我无法理解是什么提供了对具有多个语句的块中的操作数进行读写的调度或时序。 例如,在使用CPUID时需要保留EBX或RBX ,因为根据ABI,调用者拥有它。 关于EBX和RBX的使用存在一些悬而未决的问题,因此我们希望无条件地保留它(这是一项要求)。 因此需要将三个指令编码到单个ASM块中以确保指令的连续性(re:第一段中讨论的汇编器模板): unsigned int __FUNC = 1, __SUBFUNC = 0; unsigned int __EAX, __EBX, __ECX, __EDX; __asm__ __volatile__ ( “push %ebx;” “cpuid;” “pop %ebx” : “=a”(__EAX), “=b”(__EBX), “=c”(__ECX), “=d”(__EDX) : “a”(__FUNC), “c”(__SUBFUNC) ); 如果表示操作数的表达式在错误的时间点被解释,则__EBX将是保存的EBX (而不是CPUID的EBX ),如果启用了PIC,它可能是指向全局偏移表(GOT)的指针。 确切地说,表达式指定CPUID的%EBX到__EBX应该在PUSH %EBX之后发生(1); (2) CPUID ; 但(3) POP %EBX之前?

是否严格要求组装成为操作系统的“最低”部分?

我是一名中级(抽象)程序员,几个月前我开始考虑是否应该减少或增加抽象(我选择减少)。 现在,我想我已经做了大部分关于我需要的“研究”,但仍然有一些问题。 现在,虽然我“无所事事”,我只是加强了我的C技能(买了“K&R C编程朗”),并且我想(感觉舒服之后)开始学习操作系统(如minix)只是为了学习目的,但我有一个想法困在我的脑海里,我真的不知道我是否应该关心。 理论上(我认为,不确定),更高级别的语言不能直接引用硬件(如寄存器,内存位置等),因此基础的“完美语言”将是汇编。 我已经研究过汇编(前一段时间)只是为了看看它是怎么回事(由于本书使用了过时的调试器(对于Linux来说,汇编语言一步一步),我已经停在本书的中间但是从我的内容读过,我不喜欢这门语言。 所以问题很简单:操作系统(引导程序/内核)是否可以在不触及单行程序的情况下进行编程,并且仍然有效? 即使它可以,它也不会是“跨架构”,不是吗? (i386 / arm / mips等…) 感谢您的支持

从C – Bus错误10测试Shellcode

下面,我写了一个打印’Hello,World!’的x64程序集。 来自Mac OS X 10.8上的系统调用。 它独立执行时汇编并运行完美。 ; Assemble and link with: ; nasm -f macho64 -o HelloWorld.o HelloWorld.s ; ld -arch x86_64 -o HelloWorld HelloWorld.o global start section .text start: push rbp mov rbp, rsp jmp short String xor rdi, rdi mov di, 0x01 StringRet: pop rsi xor rdx, rdx mov dl, 0xE mov r8b, […]

编译背后的主要步骤是什么?

编译C程序的主要步骤是什么? 通过编译,我的意思是(可能是错误的)使用gcc从包含C代码的纯文本中获取二进制文件。 我很想了解这个过程的一些关键点: 到那天结束时,我需要将我的C代码转换为我的CPU应该理解的语言。 那么,谁在乎了解我的CPU特定指令呢? 操作系统? gcc是否将任何C转换为汇编语言? 我知道(实际猜测)对于每种处理器类型,我将需要一个汇编程序来解释(?)汇编代码并转换为我的CPU特定指令。 这个汇编程序(谁发货)在哪里? 它是否附带操作系统? 如果我用文本编辑器打开二进制文件,为什么我看不到0和1?

错误13:使用字符串文字在grub中启动简单内核时,可执行文件无效或不受支持

我写了一个简单的内核,试图将两个字符写入帧缓冲区。 如果我在内核中定义一个字符串文字,我在启动时会得到以下输出: Booting ‘os’ kernel /boot/kernel.elf Error 13: Invalid or unsupported executable format Press any key to continue… 否则,如果我定义了两个字符,我得到以下内容(注意输出开头的’ab’): abBooting ‘os’ kernel /boot/kernel.elf [Multiboot-elf, , , shtab=0x102168, entry=0x1001f0] 装载机 我在汇编中编写了加载程序: global loader ; the entry symbol for ELF MAGIC_NUMBER equ 0x1BADB002 ; define the magic number constant FLAGS equ 0x0 ; multiboot flags CHECKSUM equ […]

在没有算术运算符的情况下执行位除

我正在尝试完成一项任务,要求我为二进制算术编写三个函数。 badd()是为我提供的,所以我用它来帮助编写bsub()和bmult()函数。 但是,我无法理解如何执行bdiv()函数。 我知道我需要使用右移和我的bsubb()函数迭代这些位,但我不知道如何实现它。 以下是我到目前为止所写的function。 如果您发现我在写它们时犯了任何错误(请注意bsub()和bmult()),请告诉我。 谢谢。 /** This function adds the two arguments using bitwise operators. Your * implementation should not use arithmetic operators except for loop * control. Integers are 32 bits long. This function prints a message * saying “Overflow occurred\n” if a two’s complement overflow occurs * during the addition process. […]

如何用C语言编写linux启动代码?

我是学习OS开发的新手。 从我读过的书中,它说启动加载器会将第一个MBR复制到0x7c00,并从实模式开始。 并且,示例从16位汇编代码开始。 但是,当我查看今天的linux内核时, arch / x86 / boot有’header.S’和’boot.h’,但实际代码是在main.c中实现的。 这似乎是“不编写汇编”有用的。 但是,这是如何在Linux中专门完成的? 我可以粗略地想象可能有特殊的gcc选项和链接策略,但我看不到细节。

计数位数

重复: 计算32位整数中设置位数的最佳算法? 假设你有一个号码。 有没有办法在这个数字的二进制表示中计算等于1的位,而不是使用迭代? 我的意思是,有没有办法使用一些按位运算符和掩码在恒定时间内完成它。 我需要的解决方案适用于32位和64位架构。 啊差点忘了,我需要它用于C语言或汇编程序也很好。

Enum如何在C上分配内存?

我正在尝试使用C和Assembly(intelx8086)语言。 我也在使用一个class级,我的一个朋友给了我一个 typedef enum data_10 {a=0,b=7,c=10,} data_10_type; 我想按比例使用这个类(AKA构造它/在Assembly上销毁它)。 我的问题是,“枚举”需要多少内存?

在GCC进行的每次优化后获取汇编代码?

来自维基百科上的优化编译器 , 编译器优化通常使用一系列优化转换来实现 ,这些算法采用程序并对其进行转换以生成使用较少资源的语义上等效的输出程序。 和GCC有很多优化选择。 我想在使用不同的标志(如-O1 , -O2 , -O3等)进行编译时执行每次优化后,研究生成的程序集(一个-S给出)。 我怎样才能做到这一点? 编辑:我的输入将是C代码。