SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
segment .data
msg db "Please enter a digit ", 0xA,0xD
len equ $- msg
segment .bss
number1 resb 2
number2 resb 2
result resb 1
result2 resb 1
segment .text
msg2 db "Please enter a second digit", 0xA,0xD
len2 equ $- msg2
msg3 db "The sum is: "
len3 equ $- msg3
msg4 db "The minus is: "
len4 equ $- msg4
global _start
_start:
mov eax, SYS_WRITE ; System write
mov ebx, STDOUT ; System output
mov ecx, msg ; What to write
mov edx, len ; Length to write
int 0x80 ; Interupt Kernel
mov eax, SYS_READ ; System read
mov ebx, STDIN ;
mov ecx, number1
mov edx, 2
int 0x80
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg2
mov edx, len2
int 0x80
mov eax, SYS_READ
mov ebx, STDIN
mov ecx, number2
mov edx, 2
int 0x80
call add
add:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg3
mov edx, len3
int 0x80
;load number1 into eax and subtract '0' to convert from ASCII to decimal
mov eax, [number1]
sub eax, '0'
; do the same for number2
mov ebx, [number2]
sub ebx, '0'
; add eax and ebx, storing the result in eax
add eax, ebx
; add '0' to eax to convert the digit from decimal to ASCII
add eax, '0'
; store the result in result
mov [result], eax
; print the result digit
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, result
mov edx, 1
int 0x80
ret
minus:
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg4
mov edx, len4
int 0x80
;load number1 into eax and subtract '0' to convert from ASCII to decimal
mov eax, [number1]
sub eax, '0'
; do the same for number2
mov ebx, [number2]
sub ebx, '0'
; add eax and ebx, storing the result in eax
sub eax, ebx
; add '0' to eax to convert the digit from decimal to ASCII
add eax, '0'
; store the result in result
mov [result2], eax
; print the result digit
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, result
mov edx, 1
int 0x80
ret
mul:
;load number1 into eax and subtract '0' to convert from ASCII to decimal
mov al, [number1]
sub al, '0'
; do the same for number2
mov bl, [number2]
sub bl, '0'
; add eax and ebx, storing the result in eax
mul bl
; add '0' to eax to convert the digit from decimal to ASCII
add al, '0'
; store the result in result
mov [result], al
; print the result digit
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, result
mov edx, 1
int 0x80
ret
exit:
mov eax, SYS_EXIT
xor ebx, ebx
int 0x80
上面的代码是我到目前为止所做的,我试图添加数字,但添加函数似乎被调用两次,如下图所示。我想做的是对两个数字进行加,减,乘和除。我怎么能这样做,当我尝试添加2个数字有时它给了我输出分段错误。
答案 0 :(得分:0)
您在_start
区块的中间定义了您的功能。
在调试器中单步执行代码,并注意在call add
返回后,继续执行从add
标签开始的说明。
当你到达ret
时,即从ret
尝试_start
时(因为堆栈的顶部是argc
,而不是地址),最终会崩溃在System V ABI中的进程启动时)。或者你甚至可能早先犯错;你没有发布调试器输出,我没有在脑海里模拟它看看会发生什么。
这就是The sum is: ?
打印两次的原因。
我猜您的代码也无法处理多位数字,因此您获得了ASCII代码'0' + 8+9
或其他任何内容。请参阅How do I print an integer in Assembly Level Programming without printf from the c library?或简化的2位数最大版本。或者如果你动态链接libc,只需使用printf
,这样它就可以调用自己的init函数。