NASM - 如何使用 int 080h 打印数字?
NASM - how to print a number using int 080h?
我正在 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。这里有什么问题吗?
如果要打印 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:
我正在 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。这里有什么问题吗?
如果要打印 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: