换句话说,有什么情况我可能需要这个指令吗?
从英特尔说明手册中,这是指令的作用:
从DS加载(E)CX字节:[(E)SI]到AL.
在NASM中采用以下示例:
section .data
src: db 0, 1, 2, 3
section .code
mov esi, src
mov ecx, 4
rep lodsb ; mov al, byte[esi + ecx -1]; ecx++
Run Code Online (Sandbox Code Playgroud)
在rep lodsb执行指令时,我无法控制加载的值al.我所能做的只是等待,直到指令终止以获取最后一个值al,当然我可以直接获得,没有循环.
同样的问题也适用于家庭的休息:REP LODS AX,REP LODS EAX和REP LODS RAX.
我在NASM中编写了这段代码:
PADDD mm0, mm1
Run Code Online (Sandbox Code Playgroud)
并且没有任何错误组装,但是这条指令虽然存在于NASM中,但我在"英特尔说明手册"中找不到它,我发现的全是:
PADDD xmm1, xmm2/m128
Run Code Online (Sandbox Code Playgroud)
这需要xmm注册而不是mm注册.
这是操作码PADDD mm0, mm1:0FFEC1
这是操作码PADDD xmm0, xmm1:660FFEC1
那么为什么PADDD mm0, mm1缺少英特尔指令手册?
生成的操作码:
or ebx, 0ffffffffh
Run Code Online (Sandbox Code Playgroud)
与NASM是:
83CBFF
Run Code Online (Sandbox Code Playgroud)
但在英特尔说明手册中:
81 /1 id OR r/m32, imm32
83 /1 ib OR r/m32, imm8
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么NASM使用操作码83代替81,以及如何生成操作码81?
这是NASM的命令行: nasm -fwin32 file.asm -l list.lst
不应该返回类型的返回size_t?因为C中对象的大小属于这种类型,包括传递给的字符串printf.
a是一个数组,foo是一个函数,i是一个int.
a[++i] = foo(a[i-1], a[i]);
Run Code Online (Sandbox Code Playgroud)
上面的代码会有未定义的行为吗?
阵列索引++i,i-1并且i,保证是在阵列范围.
我知道C不是上下文无关语言,一个著名的例子是:
int foo;
typedef int foo;
foo x;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,词法分析器不知道foo第三行中是否是标识符或typedef。
我的问题是,这是使C成为上下文相关语言的唯一原因吗?
我的意思是,如果我们去掉typedef,它会成为上下文无关的语言吗?或者还有其他原因(例子)阻止它成为这样?
通过查看英特尔指令量,我发现了这个:
1)88 /r MOV r/m8,r8
2)8A /r MOV r8,r/m8
当我在NASM中写这样的一行时,用list选项组装它:
mov al, bl
我在列表中得到了这个:
88D8 mov al, bl
所以很明显NASM选择了上面两个的第一条指令,但不是第二条指令选项二吗?如果是这样,NASM在什么基础上选择了第一个?
我有两个文件:
在文件1.c中,我有以下数组:
char p[] = "abcdefg";
Run Code Online (Sandbox Code Playgroud)
在文件0.c中,我有以下代码:
#include <stdio.h>
extern char *p; /* declared as 'char p[] = "abcdefg";' in 1.c file */
int main()
{
printf("%c\n", p[3]); /* crash */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是命令行:
gcc -Wall -Wextra 0.c 1.c
Run Code Online (Sandbox Code Playgroud)
我知道extern char *p应该是:extern char p[];但我只想解释为什么它在这种特殊情况下不起作用.虽然它在这里工作:
int main()
{
char a[] = "abcdefg";
char *p = a;
printf("%c\n", p[3]); /* d */
return 0;
}
Run Code Online (Sandbox Code Playgroud) section .data
qVar1: dq 1
section .bss
var28: resb 28
section .text
_main:
; Use an MMX instruction
movq mm0, [qVar1] ; Move quadword from r/m64 to mm.
; Read Tag Word
fstenv [var28]
mov ax, [var28 + 8] ; move the Tag Word to ax
Run Code Online (Sandbox Code Playgroud)
这一刻ax是0101 0101 0101 0110
但是从英特尔手册,第9.5.1节MMX指令和x87 FPU标签字,我引用:
在每个MMX指令之后,整个x87 FPU标记字被设置为有效(00B).
那么为什么ax不是全零呢?
char* p = init();
p = foo(p); /* this one */
Run Code Online (Sandbox Code Playgroud)
功能foo原型:
char* foo(char* p);
Run Code Online (Sandbox Code Playgroud)
是允许以foo这种方式调用,还是属于未定义行为类别?