我正在NASM中编写一个程序,它接收一个字符串并计算其中有多少个字母,然后打印出结果,我必须使用080h中断来完成所有的写入和读取。我在.data部分的标签中保留了字母数:
lett: db 0 ; letter counter
然后当我找到一封信时我会增加它:
inc byte [lett]
但是当我去写STDOUT时,没有任何显示,我不确定我是否正确使用080h:
mov eax, SYSCALL_WRITE ; write the letter count to stdout
mov ebx, STDOUT ;
mov ecx, lett ;
mov edx, 1 ;
int 080h ;
我知道EDX需要包含要读取的缓冲区的长度,我假设它是1,因为我设置lett指向一个字节,初始化为0.这里有什么问题吗?
答案 0 :(得分:1)
如果要以ASCII字符串打印数字,则必须将数字转换为字符串。
这适用于非负数:
; dummy to tell the program the end of data
push -1
; set the number to convert
xor eax, eax
mov al, [lett]
; convert the number to string (sequence of character)
convert_loop:
xor edx, edx
mov ebx, 10
div ebx
add edx, '0'
push edx
test eax, eax
jnz convert_loop
; print the converted string
print_loop:
cmp dword [esp], 0
jl print_loop_end ; break when -1 is found
mov eax, 4
mov ebx, 1
mov ecx, esp
mov edx, 1
int 080h
pop eax ; move on next character
jmp print_loop
print_loop_end:
pop eax ; clean -1
更新:不使用push / pop
指令的另一个版本:
section .bss
; 32-bit unsigned integer won't be longer than 10 digits in decimal
strtonum_convert_buffer resb 12
section .text
; dummy to tell the program the end of data
mov ecx, strtonum_convert_buffer
mov byte [ecx], 0
; set the number to convert
xor eax, eax
mov al, [lett]
; convert the number to string (sequence of character)
convert_loop:
xor edx, edx
mov ebx, 10
div ebx
add edx, '0'
inc ecx
mov [ecx], dl
test eax, eax
jnz convert_loop
; print the converted string
print_loop:
cmp byte [ecx], 0
je print_loop_end ; break when 0 is found
mov eax, 4
mov ebx, 1
; there is already the pointer to the character on ecx
mov edx, 1
int 080h
dec ecx ; move on next character
jmp print_loop
print_loop_end: