我正在阅读Richard C. Detmer 撰写的题为"80x86汇编语言和计算机体系结构简介"的教科书
我有一个关于即时内存mov操作码的问题.这里也是我所指的文字部分:
继续下图4.1,下一行是即时到内存的移动.这些指令中的每一个都有操作码
C6,ModR/M字节,附加地址字节(如果需要),最后是包含立即操作数的字节.如上所述对地址进行编码以用于存储器到寄存器移动.例如,如果smallCounter引用内存中的一个字节并mov smallCounter, 100组装指令,则汇编器将生成7(3 + 4)个字节的目标代码C6 05 xx xx xx xx 64,其中xx xx xx xx表示内存中的地址,64表示字节大小的十六进制版本100 .00 000 101对于直接存储器寻址,ModR/M字节05是Mod = 00和R/M = 101,不需要Reg字段并设置为000.作为另一个示例,考虑
mov BYTE PTR [edx], -1使用寄存器间接模式的存储器目的地.操作码仍然是C6,而立即字节(总是最后一个)现在是FF为-1.第二个字节是ModR/M字节,其中Mod = 00用于寄存器间接,Reg = 000(未使用),R/M = 010用于EDX,制作00 000 010或02.目标代码用于C6 02 FF.第92页,第4章,第1节 - 复制数据
图4.1 - 带有字节目标的mov指令 - 是一个包含四列的图表:
上述部分中图中的线也是: …
我想知道MOV BYTE PTR指令究竟是如何工作的,我在这里有一个例子,我无法理解结果.核实:
MOV CL,BYTE PTR DS:[ESI]
----Ollydbg show this------
DS:[01EA22E0]=41 ('A')
CL=B0
Run Code Online (Sandbox Code Playgroud)
为什么CL = B0?为什么CL不是41?如果我在转储中去ESI,我就有这个
01EA22E0: 41 47 00 C5 B9 F1 63 3C... But any B0 ;(
Run Code Online (Sandbox Code Playgroud)
检查我的印刷品:

我真的需要解决这个问题,欢迎任何帮助.
我有一个用C#编写的客户端应用程序,想要读取MOV文件的持续时间.我必须在Windows窗体中创建并托管Quicktime COM控件,然后在其中加载影片并获取持续时间.在我的情况下,这是不可行的,因为客户端应用程序不是Windows窗体.
我实际做的另一种方法是打开MOV文件raw,检查字节,直到你在剪辑的电影标题原子('mvhd')之前的12个字节,并从那里获得时间刻度和持续时间.这个黑客我不熟悉,因为如果Apple将来更改文件格式可能无法正常工作.
我宁愿避免将MOV加载到控件中,因为我只想获得剪辑的持续时间而没有别的.理想情况下,我需要提供一个字符串,其中包含mov文件的路径到应用程序,并获得这样的持续时间.有没有人用非托管代码完成它?
我已经查看了有关如何解决这个问题的所有建议线程,我找不到符合我的错误的线程.
当我编译时,我得到"'mov'的"太多内存参考",即使我拿出所有这些...?
__asm__(
"mov 0x8(%ebp), %edx;"
"mov 0x8(%edx), %edx;"
"cmp $0x0, %edx;"
"je notFound;"
"sub $0x10, %esp;"
"movl 0xc(%ebp), (%esp);"
"movl $0x24, 0x8(%esp);"
"mainloop: "
"movl %edx, 0x4(%esp);"
"call _memcmp;"
"cmp $0xffffffff, %eax;"
"je leftBranch;"
"cmp $0x1, %eax;"
"je rightBranch;"
"jne found;"
"leftBranch: "
"mov 0xc(%edx), %edx;"
"cmp $0x0, %edx;"
"je notFound;"
"jne mainloop;"
"rightBranch: "
"mov 0x10(%edx), %edx;"
"cmp $0x0, %edx;"
"je notFound;"
"jne mainloop;"
"notFound: "
"mov $0x0, %eax;"
"add $0x10, %esp;"
"leave;"
"ret;"
"found: "
"add $0x10, …Run Code Online (Sandbox Code Playgroud) 我的任务是将 AX 和 BX 与 AX 相加,而不使用“MOV”或“LEA”操作数。我有点卡在这里,你能帮我吗?
; AX need to be 15, using ONLY 'mov' and 'lea'.
; Do NOT use arithmetic instrutions (add, inc, mul, etc.)
mov ax,10
mov bx,4
lea cx,ax
lea cx, [cx+bx]
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?抱歉我的错误,我是新手。
我已经拆解了一个使用C 函数的x86 elf二进制文件scanf.
以下是与以下内容相关的反汇编代码块scanf:
0x0804857a 89442404 mov dword [esp + 0x4], eax
0x0804857e c70424b28604. mov dword [esp], 0x80486b2
0x08048585 e8eafdffff call sym.imp.scanf
Run Code Online (Sandbox Code Playgroud)
检查时gdb,地址处的内存0x80486b2包含数据0x7325(ASCII代码中的" %s "字符串).
所以这段代码显然是在堆栈上以相反的顺序推送参数,以便用这两个参数调用.
这通常用C编码
scanfscanfscanf ("%s", &somevar);
在给定汇编代码的情况下,我所期望的是,常量的32位表示形式 0x80486b2被加载到堆栈指针所指向的地址中 ......
但是,该mov指令已经加载了32位表示的任何处于地址 0x80486b2 到堆栈指针指向的地址 ......是吗?
所以我们基本上得到的mov只是将数据从内存位置转移到另一个内存位置,根据这个x86程序集介绍(在众多其他来源中)是非法的(重点是我的):
在需要存储器传输的情况下,必须首先将源存储器内容加载到寄存器中 …
使用Z2 dword ?,mov eax, Z2工作正常,但movzx eax, Z2会出现“无效指令操作数”错误。
我在这里有点困惑:即使Z2的大小与 相同eax,为什么程序集不能接受movzx这个?似乎movzx特别希望操作数的大小不同。
设计这样的指令的原因可能是什么?
如果它被设计为简单地允许相同大小的操作数,那么编码不是更容易吗?