本文介绍了组装中的
算术运算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
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个数字时,有时会出现此输出细分错误.
The above code is what i have done so far, I tried to add the numbers but add function seems to be called twice as shown in the picture below. What am i trying to do is to add, subtract, multiply and divide the two numbers. How can i do that and when i try to add 2 numbers sometimes it gave me this output Segmentation fault.
推荐答案
您在_start块的中间定义了函数.
You defined your functions in the middle of the _start block.
在调试器中单步执行代码,请注意,在返回call add之后,执行将继续执行从add标签开始的指令.
Single-step your code in a debugger and notice that after call add returns, execution continues into the instructions starting at the add label.
最终,当您到达ret时会崩溃,即,当您尝试从_start进入ret时(因为堆栈的顶部是argc,而不是地址),在System V ABI中的进程启动时).也许您甚至更早地犯了错;您没有发布调试器输出,我也没有在脑海中模拟它以查看会发生什么.
Eventually you crash when you reach the ret, i.e. when you try to ret from _start (because the top of the stack is argc, not an address, at process startup in the System V ABI). Or maybe you even fault earlier; you didn't post debugger output and I didn't simulate it in my head to see what happens.
这就是为什么The sum is: ?打印两次的原因.
This is why The sum is: ? is printed twice.
我想您的代码也无法处理多位数字,因此您得到了ASCII代码'0' + 8+9或其他任何代码.参见如何在不使用c库中的printf的情况下,在汇编级编程中打印整数?,或该数字的简化2位数最大版本.或者,如果您动态链接libc,请使用printf,以便它可以调用自己的init函数.
I guess your code also fails to handle multi-digit numbers, so you got the ASCII code '0' + 8+9 or whatever. See How do I print an integer in Assembly Level Programming without printf from the c library?, or a simplified 2-digit-max version of that. Or just use printf if you dynamically link libc, so it can call its own init functions.
发布评论