Articles of x86

gcc编译.c与.s文件 – .bss混淆(bug?)

在IA32体系结构的Ubuntu 12.04下使用gcc 4.6.3时遇到了一个问题,那就是使用存储在.bss段上的汇编文件编译C文件,同时使用.comm和.lcomm指令。 在.comm和.lcomm缓冲区之间,汇编文件foo.s使用接近最大的空间让我在这个分区中分配(foo计算长整数的总分解)。 用一个汇编文件bar.s来处理I / O等等,所有东西都编译和链接正常(和快速),并且工作正常。 当我使用C文件bar.c处理I / O时,gcc不会终止 – 至less不会在5分钟内完成。 .bss请求接近我的小型笔记本内存,但由于.bss段没有得到编译时初始化,并与bar.s一起工作,我不明白为什么会发生这种情况。 当我减小在foo.s中请求的.bss大小时,gcc编译并链接正常,并且所有的东西都按照它应该执行的那样执行。 此外,正如所料,在每种情况下使用创build的可执行文件的文件大小 gcc bar.c foo.s -Wall 不依赖于.bss请求的大小 (我编译的大小都比原来的小,大小不一)。 在所有情况下,可执行文件都是非常小的(可能是10k),实际上它的大小是相同的,但显然,原始文件不能成功编译并挂起。 这是海湾合作委员会的错误? 有没有一个命令行选项来防止这种情况发生? 或者是怎么回事? 编辑:每个评论,这里是与.bss段分配的部分: # Sieve of Eratosthenes # Create list of prime numbers smaller than n # # Note: – no input error (range) check # – n <= 500,000,000 (could be […]

当我们将一块硬件插入计算机系统时会发生什么?

当我们将一块硬件插入计算机系统时,比方说一个网卡(网卡)或一个声卡,机箱底下会发生什么事情,以便我们使用那块硬件? 我可以想到以下两种情况,纠正我,如果我错了。 如果硬件有自己的内存芯片, 有人会安排一系列地址空间来映射这些内存芯片。 如果硬件没有自己的存储芯片, 有人会在计算机系统的主存储器中分配一定范围的地址来容纳该硬件。 我不确定前面提到的人是操作系统还是CPU。 还有一个问题:硬件总是需要一些内存来工作吗? 我对吗? 非常感谢。

Memcpy与memset相同

我想用memcpy来测量内存带宽。 我从这个答案修改了代码: 为什么vector化循环没有使用memset来衡量带宽的性能改进 。 问题是memcpy只比memset稍慢,因为我认为memcpy运行速度是内存两倍以上的两倍。 更具体地说,我运行了超过1 GB的数组a和b (分配将calloc )100次,执行以下操作。 operation time(s) —————————– memset(a,0xff,LEN) 3.7 memcpy(a,b,LEN) 3.9 a[j] += b[j] 9.4 memcpy(a,b,LEN) 3.8 请注意, memcpy只比memset慢一点。 a[j] += b[j] (其中j越过[0,LEN) )的操作应该比memcpy长三倍,因为它操作的数据量是三倍。 但是它只有memset 2.5左右。 然后我用memset(b,0,LEN)将b初始化为零并再次testing: operation time(s) —————————– memcpy(a,b,LEN) 8.2 a[j] += b[j] 11.5 现在我们看到, memcpy大约是memset两倍, a[j] += b[j]大约是memset三倍。 至less我会预期,在memset(b,0,LEN) , memcpy会比较慢,因为 100次迭代中的第一次迭代的延迟分配(第一次触发) 。 为什么我只能在memset(b,0,LEN)之后得到预期的时间? test.c的 #include <time.h> […]

C调用约定并传递参数

在Linux(或OS X)中进行函数调用时,被调用者是否可以修改堆栈中参数的值? 我是在这样的假设下,因为调用者是清理它们的那个,所以在函数调用之后它们应该包含相同的值。 但是我发现使用-O2的GCC正在修改传递给堆栈的参数。 我还查找了包括System V i386调用约定的文档,但无法find明确的答案。 这是我正在debugging的一些示例代码。 pushl %eax # %eax = 0x28 call _print_any popl %eax # %eax is now 0x0a 我会假设GCC修改堆栈上的参数是好的,但我想知道它在哪里指定它可以这样做。

在x86中将string定义为字节(db)和将string定义为字/双字(dw / dd)有什么区别?

我试图调查大会定义标签之间的差异,这里是一个例子 ALabel: db 'Testing' AAnotherLabel: dw 'Testing' 现在,让我加载到一个32位寄存器: mov eax, [ALabel] mov ebx, [AAnotherLabel] 经过gdb的调查,我发现eax和ebx的所有子寄存器都包含相同的值,请看这里: info register eax 0x64636261 //dcba info register ebx 0x64636261 //dcba 他们是一样的! 在Jeff Duntemann的书中(汇编语言使用Linux进行分步编程),他给出了一个单词和双字进入寄存器的例子,但由于某种原因加载了偏移量(即像这样的值的地址) DoubleString: dd 'Stop' mov edx, DoubleString 对edx内容的调查显示,它包含一个地址,可能是string中前四个字母的地址,与第一个地址相同,尽pipe我在这里进行了推测。 我想澄清在这里真正发生了什么,并且这个声明实际上是将string中第一个字母的地址加载到一个寄存器中: Fin: db 'Final' mov ecx, Fin

汇编语言中的分割错误

我正在学习AT&T x86汇编语言。 我试图编写一个汇编程序,它采用整数n,然后返回结果(n / 2 + n / 3 + n / 4)。 这是我所做的: .text .global _start _start: pushl $24 call profit movl %eax, %ebx movl $1, %eax int $0x80 profit: popl %ebx popl %eax mov $0, %esi movl $4, %ebp div %ebp addl %eax, %esi movl %ecx, %eax movl $3, %ebp div %ebp addl […]

有没有错误列表会显示为“segfaults”,当他们没有真正的内存访问?

在这个问题中 ,我了解到,如果不在响铃0时尝试运行特权指令,可能会导致在用户进程中看起来像段错误,并有两个后续问题。 所有特权指令都是如此吗? 还有什么其他types的错误会导致假段错误,但与试图读取内存无关?

汇编语言计算器 – Linux x86&NASM – Division

我正在用汇编语言编写一个计算器,以在x86处理器上执行。 基本上,我的计算器要求用户input两个数字,然后指出哪个操作(加法,减法,乘法和除法)要与他们做。 我的计算器加减乘法正确但无法分割 。 在划分时,我总是得到1。 然后我离开我的应用程序代码完成: section .data ; Messages msg1 db 10,'-Calculator-',10,0 lmsg1 equ $ – msg1 msg2 db 10,'Number 1: ',0 lmsg2 equ $ – msg2 msg3 db 'Number 2: ',0 lmsg3 equ $ – msg3 msg4 db 10,'1. Add',10,0 lmsg4 equ $ – msg4 msg5 db '2. Subtract',10,0 lmsg5 equ $ – […]

Linux x86:实模式地址空间在受保护的内核模式下映射到哪里?

在x86平台上运行的Linux中,实模式地址空间是在受保护的内核模式下映射到的吗? 在内核模式下,一个线程可以直接访问内核地址空间。 内核处于低8MB,页表处于某个位置等(如此处所述)。 但是实模式地址空间在哪里呢? 可以直接访问吗? 例如BIOS和BIOS插件(见这里 )?

如何获得中断向量?

当我运行“cat / proc / interrupts”时,我可以得到以下结果: CPU0 CPU1 0: 253 1878 IO-APIC-edge timer 1: 3 0 IO-APIC-edge i8042 7: 1 0 IO-APIC-edge parport0 8: 0 1 IO-APIC-edge rtc0 9: 0 0 IO-APIC-fasteoi acpi 12: 1 3 IO-APIC-edge i8042 16: 681584 60 IO-APIC-fasteoi uhci_hcd:usb3, nvidia 17: 0 0 IO-APIC-fasteoi uhci_hcd:usb4, uhci_hcd:usb7 18: 0 0 IO-APIC-fasteoi uhci_hcd:usb8 22: […]