使用 NASM 在 Assembly 中添加 2 个输入的数字
Adding 2 inputted numbers in Assembly using NASM
我已经尽力解释了我将这两个数字相加时的所有思考过程。但是,在 运行 生成的可执行文件中,我最终得到
"Sum is: j" 这显然是错误的。此外,似乎无论我给出哪个输入,总和都保持为 "j",所以一定有什么非常错误的地方。
我相信这段代码应该可以工作,但我的理解显然有缺陷。
我应该从哪里开始解决这个问题?最近才开始学汇编。
section .data ;line 1
msg db "Sum is: "
len equ $ - msg
section .bss
num1 resb 1
eol1 resb 1
num2 resb 1
eol2 resb 1
sum resb 2
section .text
global _start
print_int:
mov eax, 4 ;defining routine print_int
mov ebx, 1 ;file descriptor (stdout)
int 0x80 ;system call number (sys_write)
ret ;return back
_start:
;Read and store user input for num1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2 ;2 bytes of info
int 80h
mov byte [eol1], 0xA ; value of first end of line
;Read and store user input for num2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2 ;2 bytes of info
int 80h
mov byte [eol2], 0xA ;value of 2nd end of line
;Add num1 and num2
mov eax, num1
sub eax, '0' ;this is so that the value in 3 is set to 3 because
;'3' and '0' actually are ASCII values
mov ebx, num2
sub ebx, '0'
add eax, ebx ;Move the sum of 0x3 and 0x4 into eax
add eax, '0' ;Set eax to be the ASCII value for the result of the sum
mov [sum], eax ;Set this ascii value of the sum to sum
mov ecx, msg ;Move msg ('Sum is: ') into eax
mov edx, len ;Move len (length of msh) into edx
call print_int ; call routine print_int above
;load sum to to be printed
mov ecx, sum
mov edx, 2 ;size in bytes of sum
call print_int
mov eax, 1 ;system call number (sys_exit)
xor ebx, ebx
int 0x80 ;line 43
您的程序对用户输入的 2 个单位数字进行运算。
mov eax, num1
mov ebx, num2
在 NASM 上,这将移动这些寄存器中这些变量的地址。你要的是内容!你需要写方括号。
但是等等 - 由于输入只有一个字节的信息,您应该读取 byte-sized 寄存器 AL
和 BL
.
中的数据
mov al, [num1]
mov bl, [num2]
然后所有减法和加法也必须使用这些较小的尺寸。
sub al, '0' ;From character '0'-'9' to number 0-9
sub bl, '0'
add al, bl
add al, '0' ;From number 0-9 to character '0'-'9'
AL
中的字符就是你要打印的字符。最简单的是先在 AH
寄存器中追加换行符 0xA,然后在内存中写入 AX
。
mov ah, 0xA
mov [sum], ax
只要两个个位数之和小于 10,以上所有都是正确的。
想象一下当你输入时会发生什么。数字 5 和 8 ?
总和 (13) 需要 2 个字符,没有空间容纳额外的换行符。最大的金额将来自将 9 和 9 (18) 相加。
最佳 re-define "sum" 作为 sum resb 3
.
然后写下:
mov al, [num1]
mov bl, [num2]
sub al, '0'
sub bl, '0'
add al, bl
mov edx, 2 ;String length if single digit sum
mov ecx, sum ;Address of sum
cmp al, 10
jb SingleDigit
mov byte [ecx], '1'
inc ecx ;Move to position for the units/newline
inc edx ;String length if double digit sum
sub al, 10 ;Only keep the units
SingleDigit:
add al, '0' ;From number 0-9 to character '0'-'9'
mov ah, 0xA ;Append newline
mov [ecx], ax
mov ecx, sum
call print_int
我已经尽力解释了我将这两个数字相加时的所有思考过程。但是,在 运行 生成的可执行文件中,我最终得到 "Sum is: j" 这显然是错误的。此外,似乎无论我给出哪个输入,总和都保持为 "j",所以一定有什么非常错误的地方。
我相信这段代码应该可以工作,但我的理解显然有缺陷。
我应该从哪里开始解决这个问题?最近才开始学汇编。
section .data ;line 1
msg db "Sum is: "
len equ $ - msg
section .bss
num1 resb 1
eol1 resb 1
num2 resb 1
eol2 resb 1
sum resb 2
section .text
global _start
print_int:
mov eax, 4 ;defining routine print_int
mov ebx, 1 ;file descriptor (stdout)
int 0x80 ;system call number (sys_write)
ret ;return back
_start:
;Read and store user input for num1
mov eax, 3
mov ebx, 0
mov ecx, num1
mov edx, 2 ;2 bytes of info
int 80h
mov byte [eol1], 0xA ; value of first end of line
;Read and store user input for num2
mov eax, 3
mov ebx, 0
mov ecx, num2
mov edx, 2 ;2 bytes of info
int 80h
mov byte [eol2], 0xA ;value of 2nd end of line
;Add num1 and num2
mov eax, num1
sub eax, '0' ;this is so that the value in 3 is set to 3 because
;'3' and '0' actually are ASCII values
mov ebx, num2
sub ebx, '0'
add eax, ebx ;Move the sum of 0x3 and 0x4 into eax
add eax, '0' ;Set eax to be the ASCII value for the result of the sum
mov [sum], eax ;Set this ascii value of the sum to sum
mov ecx, msg ;Move msg ('Sum is: ') into eax
mov edx, len ;Move len (length of msh) into edx
call print_int ; call routine print_int above
;load sum to to be printed
mov ecx, sum
mov edx, 2 ;size in bytes of sum
call print_int
mov eax, 1 ;system call number (sys_exit)
xor ebx, ebx
int 0x80 ;line 43
您的程序对用户输入的 2 个单位数字进行运算。
mov eax, num1 mov ebx, num2
在 NASM 上,这将移动这些寄存器中这些变量的地址。你要的是内容!你需要写方括号。
但是等等 - 由于输入只有一个字节的信息,您应该读取 byte-sized 寄存器 AL
和 BL
.
mov al, [num1]
mov bl, [num2]
然后所有减法和加法也必须使用这些较小的尺寸。
sub al, '0' ;From character '0'-'9' to number 0-9
sub bl, '0'
add al, bl
add al, '0' ;From number 0-9 to character '0'-'9'
AL
中的字符就是你要打印的字符。最简单的是先在 AH
寄存器中追加换行符 0xA,然后在内存中写入 AX
。
mov ah, 0xA
mov [sum], ax
只要两个个位数之和小于 10,以上所有都是正确的。
想象一下当你输入时会发生什么。数字 5 和 8 ?
总和 (13) 需要 2 个字符,没有空间容纳额外的换行符。最大的金额将来自将 9 和 9 (18) 相加。
最佳 re-define "sum" 作为 sum resb 3
.
然后写下:
mov al, [num1]
mov bl, [num2]
sub al, '0'
sub bl, '0'
add al, bl
mov edx, 2 ;String length if single digit sum
mov ecx, sum ;Address of sum
cmp al, 10
jb SingleDigit
mov byte [ecx], '1'
inc ecx ;Move to position for the units/newline
inc edx ;String length if double digit sum
sub al, 10 ;Only keep the units
SingleDigit:
add al, '0' ;From number 0-9 to character '0'-'9'
mov ah, 0xA ;Append newline
mov [ecx], ax
mov ecx, sum
call print_int