大佬教程收集整理的这篇文章主要介绍了如何移动 eax 寄存器中的值,ah 和 al 左 2 个字节? x86 组装,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个关于如何在 x86 汇编 eax 寄存器中移动值的问题。我知道 32 位寄存器分解为较小的组件寄存器,低 16 位是 ax,而 16 位进一步分解为 8 位寄存器 ah 和 al。
我目前正在为 x86 汇编语言作业编写一个程序,该程序希望我仅使用 mov、add 和 sub 命令在寄存器中移动四个 8 位十六进制值。该程序首先让您通过加减来移动变量的值,这没问题。
第二部分 (phase2) 是将每个值放入每个 eax 8 位位置。但是,我知道您只能访问较低的两个 8 位位置(“ah”和“al”。)我需要以某种方式将 ah 和 al 一起移动到 eax 的前导 16 位,将添加的值推送到 ah 和还剩下两个字节的位置? (问号,因为我不知道。)我相当确定我可以将正确的值添加回 ah 和 al 以完成解决方案。
我相信这样做的方法是向 ah 添加“一些十六进制值”并保留溢出,但我似乎无法理解它的逻辑。 “从逻辑上讲,”我想说这似乎是最好的行动方案,但我不确定如何实施。而且,由于我无法解决它,所以我找不到我应该找到的隐藏算法。 Phase2 应该只有 aprx 21 行,所以我知道它不是大量的添加指令列。
任何关于如何思考这个问题的方向都将受到高度赞赏。感谢任何人。
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,DWExitCode:DWord
.data
var1 BYTE 'A'
var2 BYTE 'B'
var3 BYTE 'C'
var4 BYTE 'D'
.code
main proc
;phase1
mov al,var1; store 'A'
mov ah,var4; store 'D'
mov var1,ah; move 'D' to var1
sub ah,1; make ah 'C'
mov var4,ah; move 'C' to var4
sub ah,1; make ah 'B'
mov var3,ah; move 'B' to var3
mov var2,al; 'mov al to var2
;var1 BYTE 'D'
;var2 BYTE 'A'
;var3 BYTE 'B'
;var4 BYTE 'C'
;phase2
mov ah,var1; store 'D'
mov al,var2; store 'A'
; this is where I want to shift al and ah left two bytes
; once the first two bytes of eax equal 'DA' move 'B' 'C'
; into ah and al
mov ah,var3; store 'B'
mov al,var4; store 'C'
;eax should read 'DABC' = 44414243
invoke ExitProcess,0
main endp
end main
如果您不能像普通人一样使用 shl eax,16
,您的其他选择包括:
add eax,eax
在部分展开或完全展开的循环中重复 16 次(糟糕,缓慢)。add
方式非常接近相同的 16 个周期。 sub esp,16 ; reserve some stack space.
...
mov [esp+2],ax ; 2 byte store
mov eax,[esp] ; 4-byte reload with previous AX in the top half
mov ah,... ; overwrite whatever garbage in the low 2 bytes
mov al,...
x86 是little-endian,因此将EAX 加载/存储到addr
将AL 加载/存储到相同的addr
,将AH 加载/存储到addr+1
。,高 2 个字节来自 addr+2 和 +3。
在写入 AH 和 AL 后读取 EAX 也将强制 CPU 合并部分寄存器,如果它与完整 EAX 分开重命名 AH(也可能是 AL),但很明显,如果你限制自己只使用 ISA 的一个很小的子集那么高性能不是您的首要目标。 (有关详细信息,请参阅 Why doesn't GCC use partial registers? 和 How exactly do partial registers on Haswell/Skylake perform? WriTing AL seems to have a false dependency on RAX,and AH is inconsistent。)
店铺转发摊位部分见Can modern x86 implementations store-forWARD from more than one prior store?
根据你对新的低部分(新的 AH 和 AL)做了多少,你实际上可能在一个单独的寄存器中做它们(比如 DH 和 DL),所以无序的 exec 可以开始这工作,没有对存储转发重新加载的错误依赖,特别是在不与 EAX 分开重命名 AL(甚至 AH)的 CPU 上。 (即不是 Intel P6 系列的 CPU,如硬皮的老 Nehalem)。
所以你会这样做
mov [esp+2],[esp] ; 4-byte reload with previous AX in the top half
mov dl,...
mov dh,...
... more computation with these two
mov ax,dx ; replace low 2 bytes of EAX
@H_708_13@mov ax,dx 可能需要等待旧的 EAX 值“准备好”,即重新加载完成,以便它可以合并到它作为运行该指令的一部分。 (在英特尔 SAndybridge 系列和所有非英特尔 CPU 上。)因此,这让 DL/DH 上的计算与存储转发延迟重叠。
需要说明的是,所有关于权衡的讨论都是关于性能的,而不是正确性;我在这里展示的所有方法都是完全正确的。(除非我犯了错误:P)
以上是大佬教程为你收集整理的如何移动 eax 寄存器中的值,ah 和 al 左 2 个字节? x86 组装全部内容,希望文章能够帮你解决如何移动 eax 寄存器中的值,ah 和 al 左 2 个字节? x86 组装所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。