程序集

时间:2018-01-17 03:26:59

标签: assembly x86

        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个数字有时它给了我输出分段错误。enter image description here

1 个答案:

答案 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函数。