这是我的一位教授之前提出的问题,我假设8位寄存器是CL或CH。我通过将01H移到CH寄存器来使其工作,但我想知道是否有其他方法可以做到这一点,因为在运行代码时,我在技术上将16位CX寄存器作为一个整体使用。我的参考代码:
MOV CH,01H L1:INC AX ;to keep count LOOP L1
4ktjp1zp1#
你是对的,你的代码使用了16位CX。更糟糕的是,它依赖于CL在这个代码段执行之前为零!一个从零开始的8位循环计数器将在256次递减(或递增)后返回零。
mov al, 0 ; uint8_t i = 0. xor ax,ax is the same code size but zeros AH loop_top: ; do { dec al jnz loop_top ; }while(--i != 0)
这个问题中没有任何内容表明循环内部需要任何工作;这只是一个空的延迟环路。
效率说明:dec ax比dec al小,loop rel8比dec/jnz更紧凑。因此,如果您针对真实的的8086或8088进行优化,您会希望保持循环体更小,因为它比循环前面的代码运行的次数更多。当然,如果您实际上只想延迟,这将延迟更长的时间,因为代码获取将占用更多的内存访问。对于mov ax, 256(3字节)与xor ax,ax(2字节)或mov al, 0(2字节),总代码大小是相同的。
dec ax
dec al
loop rel8
dec
jnz
mov ax, 256
xor ax,ax
mov al, 0
这对于任何8位寄存器都是一样的; AL对于这些指令中的任何一条都不是特殊的,所以您通常希望让它自由地用于那些可以受益于其特殊编码的东西,比如cmp al, imm8在2个字节中而不是通常的3个字节。(mov al, 0 vs. xor al,al-在许多现代CPU上都存在错误依赖。mov ah,0可能避免了对Skylake的错误依赖;至少mov从另一个寄存器执行,但可能不是立即数。参见 * How exactly do partial registers on Haswell/Skylake perform? Writing AL seems to have a false dependency on RAX, and AH is inconsistent *。无论如何,异或归零通常对字节寄存器没有用。)
cmp al, imm8
xor al,al
mov ah,0
mov
1条答案
按热度按时间4ktjp1zp1#
你是对的,你的代码使用了16位CX。更糟糕的是,它依赖于CL在这个代码段执行之前为零!一个从零开始的8位循环计数器将在256次递减(或递增)后返回零。
这个问题中没有任何内容表明循环内部需要任何工作;这只是一个空的延迟环路。
效率说明:
dec ax
比dec al
小,loop rel8
比dec
/jnz
更紧凑。因此,如果您针对真实的的8086或8088进行优化,您会希望保持循环体更小,因为它比循环前面的代码运行的次数更多。当然,如果您实际上只想延迟,这将延迟更长的时间,因为代码获取将占用更多的内存访问。对于mov ax, 256
(3字节)与xor ax,ax
(2字节)或mov al, 0
(2字节),总代码大小是相同的。这对于任何8位寄存器都是一样的; AL对于这些指令中的任何一条都不是特殊的,所以您通常希望让它自由地用于那些可以受益于其特殊编码的东西,比如
cmp al, imm8
在2个字节中而不是通常的3个字节。(
mov al, 0
vs.xor al,al
-在许多现代CPU上都存在错误依赖。mov ah,0
可能避免了对Skylake的错误依赖;至少mov
从另一个寄存器执行,但可能不是立即数。参见 * How exactly do partial registers on Haswell/Skylake perform? Writing AL seems to have a false dependency on RAX, and AH is inconsistent *。无论如何,异或归零通常对字节寄存器没有用。)