我想问为什么我们要处理R8到R15中的低字节,为什么不使用高字节?我们可以使用低字节但不可以使用高字节
Haswell现在有2个分支单位 - 如下所示:http://arstechnica.com/gadgets/2013/05/a-look-at-haswell/2/
这是否意味着Haswell是双路径执行CPU?
在:http://ditec.um.es/~jlaragon/papers/aragon_ICS02.pdf
这是否意味着Haswell只能在整数ALU和Shift(端口6)上执行第二个分支,而不能在其他端口上的任何其他ALU上执行?
我目前正在通过反汇编C程序并试图了解它们的作用来进行汇编阅读.
我被困在一个简单的问题:一个简单的你好世界计划.
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, world!");
return(0);
}
Run Code Online (Sandbox Code Playgroud)
当我拆卸主要时:
(gdb) disassemble main
Dump of assembler code for function main:
0x0000000000400526 <+0>: push rbp
0x0000000000400527 <+1>: mov rbp,rsp
0x000000000040052a <+4>: mov edi,0x4005c4
0x000000000040052f <+9>: mov eax,0x0
0x0000000000400534 <+14>: call 0x400400 <printf@plt>
0x0000000000400539 <+19>: mov eax,0x0
0x000000000040053e <+24>: pop rbp
0x000000000040053f <+25>: ret
Run Code Online (Sandbox Code Playgroud)
我理解前两行:基本指针保存在堆栈上(通过push rbp,这会导致堆栈指针的值减少8,因为它已经"增长")并且堆栈指针的值被保存在基指针中(这样,参数和局部变量可以分别通过正偏移和负偏移轻松到达,而堆栈可以保持"增长").
第三行提出了第一个问题:为什么0x4005c4("Hello,World!"字符串的地址)在edi寄存器中移动而不是在堆栈中移动?printf函数不应该将该字符串的地址作为参数吗?据我所知,函数从堆栈中获取参数(但在这里,看起来参数放在该寄存器中:edi)
在StackOverflow上的另一篇文章中,我读到"printf @ ptl"就像一个调用真正的printf函数的存根函数.我试图反汇编这个功能,但它变得更加混乱:
(gdb) disassemble printf
Dump of assembler code for function __printf:
0x00007ffff7a637b0 <+0>: sub rsp,0xd8
0x00007ffff7a637b7 <+7>: test al,al …Run Code Online (Sandbox Code Playgroud) 我正在阅读Duntemann的书(第3版),刚刚开始学习x86汇编.我正在使用Fedora 23(64位)的变体.以下是代码:
section .data
section .text
global _start
_start:
nop
; Put your experiments between the two nops...
mov eax,0FFFFFFFFh
mov ebx,02Dh
dec ebx
inc eax
; Put your experiments between the two nops...
nop
Run Code Online (Sandbox Code Playgroud)
我的makefile如下:
sandbox: sandbox.o
ld -o sandbox sandbox.o -melf_i386
sandbox.o: sandbox.asm
nasm -f elf -g -F stabs sandbox.asm -l sandbox.lst
Run Code Online (Sandbox Code Playgroud)
所以你可以看到我已经注意组装一个32位可执行文件,而不是64位.然而,问题在于,在dec ebx指令之前,AF并且SF没有设置标志与书所声称的相反.运行该程序insight向我显示32位寄存器,进一步确保可执行文件为32位.以下是gdb在dec ebx指令之前显示的状态.
(gdb) info reg
eax 0xffffffff -1
ecx 0x0 0
edx 0x0 …Run Code Online (Sandbox Code Playgroud) 大多数英特尔处理器都有2个负载单元和1个存储单元.商店单位也是一个负载单位吗?指令/微操作是修改现有的存储器数据,例如inc [memory]只使用1个存储单元,其余2个负载单元可用于可在相同周期内执行的其他微操作/指令,或者指令如inc1个负载单元(加载现有值)加1个存储单元(存储新值)所以我们只剩下一个加载单元?因此,保持2个负荷单位供选择,我们就可以完全存储指令一样mov,push等?
GCC和Clang编译器似乎采用了一些黑暗魔法.该C代码只是否定了双重的价值,但汇编指令涉及逐位XOR和指令指针.有人可以解释发生了什么,为什么它是一个最佳解决方案.谢谢.
test.c的内容:
void function(double *a, double *b) {
*a = -(*b); // This line.
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编程序指令:
(gcc)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 66 0f 57 05 00 00 00 xorpd xmm0,XMMWORD PTR [rip+0x0] # c <function+0xc>
b: 00
c: f2 0f 11 07 movsd QWORD PTR [rdi],xmm0
10: c3 ret
Run Code Online (Sandbox Code Playgroud)
(clang)
0000000000000000 <function>:
0: f2 0f 10 06 movsd xmm0,QWORD PTR [rsi]
4: 0f 57 05 00 00 …Run Code Online (Sandbox Code Playgroud) 我有一些汇编代码,我真的不明白.我的想法是没有意义.不幸的是,我无法提供更多的指导信息.C的输出是什么?
0x1000: iretd
0x1001: cli
0x1002: in eax, dx
0x1003: inc byte ptr [rdi]
0x1005: add byte ptr [rax], al
0x1007: add dword ptr [rbx], eax
0x1009: add byte ptr [rax], al
0x100b: add byte ptr [rdx], 0
0x100e: add byte ptr [rax], al
Run Code Online (Sandbox Code Playgroud)
谢谢
你好论坛 - 我有一些关于SIMD内在的类似/相关问题我在网上搜索了包括stackoverflow但没有找到好的答案所以请求你的帮助.
基本上我试图理解64位CPU如何在一次读取中获取所有128位,以及这种操作的要求是什么.
我是汇编语言的新手.我正在尝试下面的代码,你可以看到下面的代码.
bits 64
global _start
section .text
_start:
mov rcx, 1234567890
xor rcx, rcx
mov rcx, 'wxyz'
mov rax, 60
mov rdi, 0
syscall
Run Code Online (Sandbox Code Playgroud)
我想知道为什么数字在寄存器中存储为Big endian,字符作为Little-endian存储在寄存器中
我以为只在内存中,数据存储为Little endian.但我不明白为什么字符在寄存器中存储为Little endian.请告诉我.
谢谢.
代码:
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
typedef unsigned int uint32_t;
float average(int n_values, ... )
{
va_list var_arg;
int count;
float sum = 0;
va_start(var_arg, n_values);
for (count = 0; count < n_values; count += 1) {
sum += va_arg(var_arg, signed long long int);
}
va_end(var_arg);
return sum / n_values;
}
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
printf("hello world!\n");
uint32_t t1 = 1;
uint32_t t2 = 4;
uint32_t t3 = 4;
printf("result:%f\n", average(3, t1, t2, t3));
return …Run Code Online (Sandbox Code Playgroud)