2013-09-16 172 views
0

我是一名开发人员,他使用高级语言,在业余时间学习汇编语言。请参考下面的NASM程序:NASM加法程序

section .data 

section .bss 

section .text 
global main 
main: 
    mov eax,21 
    mov ebx,9 
    add eax,ebx 
    mov ecx,eax 
    mov eax,4 
    mov ebx,1 
    mov edx,4 
    int 0x80 
push ebp 
mov ebp,esp 

mov esp,ebp 
pop ebp 
ret 

下面是我使用的命令:

伊恩@ Ubuntu的:〜/桌面/ NASM/Program4 $ NASM -f精灵-o asm.o SystemCalls.asm ian @ ubuntu:〜/ Desktop/NASM/Program4 $ gcc -o program asm.o ian @ ubuntu:〜/ Desktop/NASM/Program4 $ ./程序

我没有收到任何错误,打印到终端。我使用以下链接确保寄存器包含正确的值:http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html

+0

'sys_call'写入字符串,而不是整数。它期望在'ecx'中有一个字符串指针,但是你给它的值是'30'。 – Michael

回答

1

您必须将整数值转换为字符串才能使用sys_write(系统调用4)打印它。转换可以这样完成(未经测试):

; Converts the integer value in EAX to a string in 
; decimal representation. 
; Returns a pointer to the resulting string in EAX. 
int_to_string: 
    mov byte [buffer+9],0 ; add a string terminator at the end of the buffer 
    lea esi,[buffer+9] 
    mov ebx,10    ; divisor  
int_to_string_loop: 
    xor edx,edx   ; clear edx prior to dividing edx:eax by ebx 
    div ebx    ; EAX /= 10 
    add dl,'0'    ; take the remainder of the division and convert it from 0..9 -> '0'..'9' 
    dec esi    ; store it in the buffer 
    mov [esi],dl 
    test eax,eax 
    jnz int_to_string_loop ; repeat until EAX==0 
    mov eax,esi 
    ret 

buffer: resb 10 
+0

谢谢+1。是否有任何文档解释我的链接的“名称”列中的信息,例如解释什么是sys_exit? – w0051977

+0

[本页](http://asm.sourceforge.net/syscall.html)简要介绍了系统调用的内容。 – Michael

+0

谢谢。最后一个问题。如果你想打印到页面,你是否总是需要转换为字符串? – w0051977

0

汇编程序设计需要了解ASCII代码和一些基本的转换例程。例如:十六进制转为十进制,十进制转为十六进制是保存某些存储位置的良好例程。 没有寄存器可以被打印,你必须转换(很多)。 要更有帮助: ASCII 0不会打印任何内容,但某些文本编辑器(kate linux中的kate)会在屏幕上显示某些内容(正方形或...)。在像C和C++这样的高级语言中,它用来表示NULL指针和字符串结尾。 有用也计算字符串长度。 10是行尾。根据Linux或Windows,还会有回车(Linux)(Windows/Dos)。 13回车 1B是ESC键(Linux用户现在更多关于此) 255是一个硬回报,我从不知道它为什么好,但它必须有它的目的。 检查http://www.asciitable.com/为整个列表。

-1

将整数值转换为字符串。 这里我用宏包并解压到整数转换为字符串和宏观解包做反之亦然

%macro write 2 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, %1 
    mov edx, %2 
    int 80h 
%endmacro 

%macro read 2 
    mov eax,3 
    mov ebx,0 
    mov ecx,%1 
    mov edx,%2 
    int 80h 
%endmacro 


%macro pack 3 ; 1-> string ,2->length ,3->variable 
    mov esi, %1 
    mov ebx,0 
    %%l1: 
    cmp byte [esi], 10 
    je %%exit 

    imul ebx,10 
    movzx edx,byte [esi] 
    sub edx,'0' 
    add ebx,edx 
    inc esi 
    jmp %%l1 
    %%exit: 
    mov [%3],ebx 
%endmacro 

%macro unpack 3 ; 1-> string ,2->length ,3->variable 
    mov esi, %1 
    mov ebx,0 
    movzx eax, byte[%3] 
    mov byte[%2],0 

    cmp eax, 0 
    jne %%l1 
    mov byte[%2],1 
    push eax 
    jmp %%exit2 

    %%l1: 
    mov ecx,10 
    mov edx,0 
    div ecx 
    add edx,'0' 
    push edx 
    inc byte[%2] 
    cmp eax, 0 
    je %%exit2 

    jmp %%l1 

    %%exit2: 
    movzx ecx,byte[%2] 
    %%l2: 
    pop edx 
    mov [esi],dl 
    inc esi 
    loop %%l2 
%endmacro 

section .data  ; data section 
msg1: db "First number : " ; 
len1: equ $-msg1  ; 
msg2: db "Second number : " ; 
len2: equ $-msg2  ;     
msg3: db "Sum : " ; 
len3: equ $-msg3  ; 
ln: db 10 
lnl: equ $-ln 
var1: resb 10 
var2: resb 10 
str1: resb 10 
str2: resb 10 
ans: resb 10 
ansvar: resb 10 
ansl: db '' 
l1: db '' 
l2: db '' 

section.text  ;code 
global _start 
_start: 
    write msg1,len1 
    read str1,10  
    pack str1,l1,var1 

    write msg2,len2 
    read str2,10  
    pack str2,l2,var2  

    mov al,[var1] 
    add al,[var2] 

    mov [ansvar],al 
    unpack ans,ansl,ansvar 
    write msg3,len3 
    write ans,10 
    write ln,lnl 

    mov ebx,0  ; exit code, 0=normal 
    mov eax,1  ; exit command to kernel 
    int 0x80  ; interrupt 80 hex, call kernel 

汇编器,连接和运行:

nasm -f elf add.asm 
ld -s -o add add.o 
./add 
+0

执行:nasm -f elf add.asm(say); ld -s -o add add.o; ./add –

+0

打包和解包是不明确的名称。您是否考虑过使用宏名称对其进行更具描述性的描述,以便代码可读?我必须真正阅读宏代码才能知道发生了什么。没有关于宏的描述,模糊的使用信息等。这或多或少是没有任何解释的代码转储。我还要指出,你的例子中的代码是GAS,OP是在询问NASM。 –