我的系統是 ubuntun 16.04 32bits nasm
我寫了一個接受輸入“str_a str_b”的代碼,它會給你str_a的長度和str_b的長度。
但是如果我輸入“1 1”,str_a的長度應該是1,但是當我輸出它時,它是3。如果我輸入“11 11”,輸出就變成了5,這幾乎讓我發瘋。當str_a的長度為“1 1”時,我嘗試列印一個“a”,它只列印了一次。
這是核心代碼
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
這是整個檔案,因為我試圖做其他事情,它看起來很丑
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
uj5u.com熱心網友回復:
len_a resb 0 len_b resb 0 num_a resb 23
因為resb 0根本不保留任何位元組,所以這 3 個標簽實際上指向同一個記憶體位元組。代碼等價于:
len_a:
len_b:
num_a resb 23
因此,您應用于len_a和len_b的增量將相加。這就是為什么你會得到意想不到的結果。你需要的是len_a resb 1 len_b resb 1。
dec byte[len_b] popa ret
對于begin_input_and_stroge例程的另一個問題,這是對len_b變數的丑陋且可能是最后一刻的修正。當set_num_a回圈找到一個空格字符并且您轉換到set_num_b回圈時,您確實應該跳過該字符 ( ) 而不是將它與最后的零位元組進行比較。因為那個 "" <> 0,肯定會在不需要的.inc edxcmpinc byte [len_b]
我在下面的代碼中洗掉了ECX多余的操作:
...
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
在注釋掉的部分中,有一行內容如下:
; mov ecx,dword[len_a]
對您使用的尺寸要格外小心。如果將len_a變數定義為byte,則需要在整個程式中始終如一地使用它。如果您需要從該位元組大小的變數加載雙字暫存器ECX,您可以使用MOVZX:
movzx ecx, byte [len_a]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/332880.html
