我想将整个数据段向右移动2个字节,同时在nasm中优化大小我最好的想法是:
std pusha push es push ds pop es mov si, bp lea cx, [bp+0x1] lea di, [bp+0x2] rep movsb pop es popa
字符串但它需要17个字节。。
oxf4rvwz1#
设置rep movsb的开销似乎不值得,所以让我们做一个简单的循环。
rep movsb
4 00000000 89EB mov bx, bp 5 00000002 43 inc bx 6 again: 7 00000003 4B dec bx 8 00000004 8A07 mov al, [bx] 9 00000006 884702 mov [bx+2], al 10 00000009 75F8 jnz again
字符串在开始时笨拙的inc bx是为了避免off-by-one错误,因为我们必须复制bp+1字节。如果不是因为dec没有设置进位标志,我们可以通过以下方式去掉一个字节:
inc bx
bp+1
dec
4 00000000 89EB mov bx, bp 5 again: 6 00000002 8A07 mov al, [bx] 7 00000004 884702 mov [bx+2], al 8 00000007 4B dec bx 9 00000008 72F8 jnc again ; BUG
型因此我们有效地将bx与-1而不是与0进行比较。但是,如果bp保证小于32 K,那么您可以使用jns again并减少到10个字节。我还尝试了一些使用lodsb / mov [si+3], al和df=1的版本来一起执行加载和递减,但问题是,由于lodsb没有设置标志,我们需要像cmp si, -1这样的东西来检查循环终止,这又增加了三个字节。所以我不能得到比11更短的版本。
bx
bp
jns again
lodsb / mov [si+3], al
df=1
lodsb
cmp si, -1
1条答案
按热度按时间oxf4rvwz1#
11字节
设置
rep movsb
的开销似乎不值得,所以让我们做一个简单的循环。字符串
在开始时笨拙的
inc bx
是为了避免off-by-one错误,因为我们必须复制bp+1
字节。如果不是因为
dec
没有设置进位标志,我们可以通过以下方式去掉一个字节:型
因此我们有效地将
bx
与-1而不是与0进行比较。但是,如果bp
保证小于32 K,那么您可以使用jns again
并减少到10个字节。我还尝试了一些使用
lodsb / mov [si+3], al
和df=1
的版本来一起执行加载和递减,但问题是,由于lodsb
没有设置标志,我们需要像cmp si, -1
这样的东西来检查循环终止,这又增加了三个字节。所以我不能得到比11更短的版本。