【发布时间】:2013-07-26 01:19:26
【问题描述】:
我写了一个程序,它的行为应该类似于 for while 循环,打印一个文本字符串一定次数。
代码如下:
global _start
section .data
msg db "Hello World!",10 ; define the message
msgl equ $ - msg ; define message length
; use minimal size of storage space
imax dd 0x00001000 ; defines imax to be big!
section .text
_start:
mov r8, 0x10 ; <s> put imax in r8d, this will be our 'i' </s>
; just attempt 10 iterations
_loop_entry: ; loop entry point
mov eax, 4 ; setup the message to print
mov ebx, 1 ; write, stdout, message, length
mov ecx, msg
mov edx, msgl
int 0x80 ; print message
; this is valid because registers do not change
dec r8 ; decrease i and jump on not zero
cmp r8,1 ; compare values to jump
jnz _loop_entry
mov rax, 1 ; exit with zero
mov rbx, 0
int 0x80
我遇到的问题是程序运行到无限循环中。我在 gdb 中运行它,原因是:
调用int 0x80 来打印消息,这可以正常工作,但是在中断完成后,r8 的内容被设置为零,而不是它应该是的值。 r8 是计数器所在的位置,计数(向下)打印字符串的次数。
int 0x80 是否修改寄存器值?我注意到 rax、rbx、rcx、rdx 没有受到同样的影响。
测试结果
回答:是的!它确实修改了 r8。
我在我的程序中改变了两件事。首先我现在cmp r8, 0,来获取Hello World!正确的次数,以及
我已经添加了
mov [i], r8 ; put away i
_loop_entry:之后
我也添加了
mov r8, [i] ; get i back
在第一个int 0x80之后。
这是我现在正在运行的程序。更多关于 C++ 性能的信息。
;
; main.asm
;
;
; To be used with main.asm, as a test to see if optimized c++
; code can be beaten by me, writing a for / while loop myself.
;
;
; Absolute minimum code to be competative with asm.
global _start
section .data
msg db "Hello World!",10 ; define the message
msgl equ $ - msg ; define message length
; use minimal size of storage space
imax dd 0x00001000 ; defines imax to be big!
i dd 0x0 ; defines i
section .text
_start:
mov r8, 0x10 ; put imax in r8d, this will be our 'i'
_loop_entry: ; loop entry point
mov [i], r8 ; put away i
mov eax, 4 ; setup the message to print
mov ebx, 1 ; write, stdout, message, length
mov ecx, msg
mov edx, msgl
int 0x80 ; print message
; this is valid because registers do not change
mov r8, [i] ; get i back
dec r8 ; decrease i and jump on not zero
cmp r8,0 ; compare values to jump
jnz _loop_entry
mov rax, 1 ; exit with zero
mov rbx, 0
int 0x80
【问题讨论】:
-
在 64 位代码中使用时,32 位
int 0x80ABI 会将r8-r11归零并保留其他所有内容。
标签: linux assembly gdb 64-bit nasm