my system is ubuntun 16.04 32bits nasm
I wrote a code which take an input "str_a str_b",and it will give you the length of str_a and length of str_b.
However if I input"1 1",length of str_a supposed to be 1,but when I output it ,it was 3.If I input "11 11",the output just became 5,this almost drive me crazy. And I try to print an "a" when increase length of str_a when it is"1 1",it was just printed for one time.
here is the core code
begin_input_and_stroge:
;input
pusha
mov eax, 3
mov ebx, 2
mov ecx, input
mov edx, 50
int 80h
mov byte[len_a],0
mov byte[len_b],0
mov edx,0
mov ecx,0
set_num_a:
cmp byte[input edx]," " ;if meet " ",it will start calculate length of b
je set_num_b_ini
inc byte[len_a]
inc edx
inc ecx
jmp set_num_a
set_num_b_ini:
mov ecx,0
set_num_b:
cmp byte[input edx],0
je finish_input_and_stroge
inc byte[len_b]
inc edx
inc ecx
jmp set_num_b
finish_input_and_stroge:
dec byte[len_b]
popa
ret
and it is the whole file,because I tried to do something else,it look quite ugly
section .data ;Data segment
rev_a TIMES 23 db 0
rev_b TIMES 23 db 0
text db "split"
space db " "
string db '===========', 0Ah
length equ 13
;rev_a the reverse array of a ,[3,2,1]
;num_a the string of a [1,2,3]
;len_a the length of num_a
section .bss ;Uninitialized data
copy_text resb 50
input resb 50
len_a resb 0
len_b resb 0
num_a resb 23
num_b resb 23
flag resb 0
output_len resb 10
print_test resb 10
section .text ;Code Segment
global _start
_start:
call begin_input_and_stroge
mov ecx,0
mov al,byte[len_a]
add al,"0"
mov byte[print_test ecx],al
call output
mov al,"0"
mov byte[print_test ecx],al
call output
; mov al,"0"
; mov byte[print_test],al
; call output
; mov al,byte[len_b]
; add al,"0"
; mov byte[print_test],al
; call output
; mov edx,0
; mov ecx,0
; mov ecx,dword[len_a]
; dec ecx
; output_num_a:
; cmp ecx,0
; je finish_output_num_a
; mov al,byte[num_a ecx]
; mov byte[print_test edx],al
; inc edx
; dec ecx
; jmp output_num_a
; finish_output_num_a:
; call output
; Exit code
mov eax, 1
mov ebx, 0
int 80h
output:
pusha
mov eax, 4
mov ebx, 1
mov ecx, print_test
mov edx, 10
int 80h
popa
ret
begin_input_and_stroge:;输入 ,并将其存储进字符串,同时记录相应的长度
;input
pusha
mov eax, 3
mov ebx, 2
mov ecx, input
mov edx, 50
int 80h
mov byte[len_a],0
mov byte[len_b],0
mov edx,0
mov ecx,0
set_num_a:
cmp byte[input edx]," ";若是空格,开始给num_b设置值
je set_num_b_ini
; mov al,byte[input edx]
; sub al,"0"
; mov byte[num_a ecx],al
inc byte[len_a]
; mov al,"a"
; mov byte[print_test],al
; call output
inc edx
inc ecx
jmp set_num_a
set_num_b_ini:
mov ecx,0
set_num_b:
cmp byte[input edx],0
je finish_input_and_stroge
; mov al,byte[input edx]
; sub al,"0"
; mov byte[num_b ecx],al
inc byte[len_b]
inc edx
inc ecx
jmp set_num_b
finish_input_and_stroge:
dec byte[len_b];len_b减去1
popa
ret
CodePudding user response:
len_a resb 0 len_b resb 0 num_a resb 23
Because resb 0
does not reserve any bytes at all, those 3 labels actually point to the same memory byte. The code is equivalent to:
len_a:
len_b:
num_a resb 23
Therefore the increments that you apply to len_a and len_b will add up. That's why you get the unexpected results. What you need is len_a resb 1
len_b resb 1
.
dec byte[len_b] popa ret
This is an ugly and probably last minute correction on the len_b variable for another problem with the begin_input_and_stroge routine. When the set_num_a loop has found a space character and you transition to the set_num_b loop, you really should skip that character (inc edx
) instead of comparing it to the final zero byte. Because that " " <> 0, the cmp
is certain to fall through in an unwanted inc byte [len_b]
.
I the below code I removed the operations on ECX
that were redundant:
...
xor edx, edx
mov [len_b], dl
set_num_a:
cmp byte [input edx], " "
je set_num_b_ini
inc edx
jmp set_num_a
set_num_b_ini:
mov [len_a], dl
inc edx ; Skip the " "
set_num_b:
cmp byte [input edx], 0
je finish_input_and_stroge
inc byte [len_b]
inc edx
jmp set_num_b
finish_input_and_stroge:
popa
ret
In the commented-out section you have a line that reads:
; mov ecx,dword[len_a]
Be extra careful with the sizes that you use. If you define the len_a variable as byte, you need to use it that way consistently throughout the program. If you need to load the dword register ECX
from that byte-sized variable you can use MOVZX
:
movzx ecx, byte [len_a]