我正在编写一个简单的程序来打印“Hello,world!”十六进制ASCII字符。 这是我的代码:
SECTION .DATA
msg db 'Printing Hello world in ASCII values: ', 0
msglen EQU $-msg
char1 db 064h ; 'd' character
char2 db 06Ch ; 'l' character
char3 db 072h ; 'r'
char4 db 06Fh ; 'o'
char5 db 077h ; 'w'
char6 db 020h ; (space)
char7 db 06Fh ; 'o'
char8 db 06Ch ; 'l'
char9 db 06Ch ; 'l'
char10 db 065h ; 'e'
char11 db 048h ; 'H'
SECTION .bss
SECTION .text
GLOBAL _start:
_start:
nop
mov esi, 0
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msglen
int 80h
; printing 'H'
mov eax, 4
mov ebx, 1
mov ecx, char11
mov edx, 1
int 80h
; printing 'e'
mov eax, 4
mov ebx, 1
mov ecx, char10
mov edx, 1
int 80h
; printing 'l'
mov eax, 4
mov ebx, 1
mov ecx, char9
mov edx, 1
int 80h
; printing 'l'
mov eax, 4
mov ebx, 1
mov ecx, char8
mov edx, 1
int 80h
; printing 'o'
mov eax, 4
mov ebx, 1
mov ecx, char7
mov edx, 1
int 80h
; printing space
mov eax, 4
mov ebx, 1
mov ecx, char6
mov edx, 1
int 80h
; printing 'w'
mov eax, 4
mov ebx, 1
mov ecx, char5
mov edx, 1
int 80h
; printing 'o'
mov eax, 4
mov ebx, 1
mov ecx, char4
mov edx, 1
int 80h
; printing 'r'
mov eax, 4
mov ebx, 1
mov ecx, char3
mov edx, 1
int 80h
; printing 'l'
mov eax, 4
mov ebx, 1
mov ecx, char2
mov edx, 1
int 80h
; printing 'd'
mov eax, 4
mov ebx, 1
mov ecx, char1
mov edx, 1
int 80h
; end
mov eax, 1
mov ebx, 0
int 80h
我的问题:
我该怎么做:
loop:
mov eax, 4
mov ebx, 1
mov ecx, char[incremented variable]
mov edx, 1
int 80h
inc (incremented variable)
jmp loop
我的意思是如何将变量和递增计数器作为一个变量读取?
提前致谢。
答案 0 :(得分:1)
你需要为你的字符串创建一个数组,就像声明msg
一样,加载指向该字符串的指针,取消引用以获取该字符,检查它是否为0,如果是,则中断,否则打印并递增指针。
例如:( MASM语法,抱歉)
msg2 BYTE "Hello World!",0
MOV ESI, OFFSET msg2
LOOP1:
MOVZX ECX, BYTE PTR[ESI]
TEST ECX,ECX
JE NEXT
MOV EAX, 4
MOV EBX, 1
MOV EDX, 1
INT 80h
INC ESI
JMP LOOP1
NEXT:
...
注意到你的标题声明x86-64,但是你的代码(和我的代码)是纯x86,如果你真的想要x64代码,那么系统调用的ABI会有所改变,但其余的几乎是相同。
答案 1 :(得分:0)
将角色置于ecx中是行不通的! (段错)ecx希望成为地址(偏移)。
mov ecx, mystring ; address! (Masm uses "offset")
looptop:
cmp byte [ecx], 0 ; "[contents]"
jz done
mov edx, 1 ; length
mov ebx, 1 ; stdout
mov eax, 4 ; __NR_write
int 80h
inc ecx ; next address
jmp looptop
done:
...
mov ecx, mystring ; address! (Masm uses "offset")
looptop:
cmp byte [ecx], 0 ; "[contents]"
jz done
mov edx, 1 ; length
mov ebx, 1 ; stdout
mov eax, 4 ; __NR_write
int 80h
inc ecx ; next address
jmp looptop
done:
...
...类似的东西...如果你真的想要64位代码,系统调用数字是不同的 - 1代表写入,... 3Ch(?)代表退出。使用代替'int 80h`(当然还有64位regs)。如果要使用64位ld执行32位代码,请告诉ld“-m elf_i386”。
答案 2 :(得分:0)
等一下。您是否要打印字符的十六进制值(文本中)而不是字符?像这样的东西? (高度未经优化)
global _start
section .data
msg db "Hello World", 0
hexbuf db "0xXX, "
hexbuflen equ $ - hexbuf
section .text
_start:
mov esi, msg
looptop:
mov al, [esi]
test al, al
jz done
inc esi
mov ah, al
and al, 0Fh
cmp al, 9
jna skip
add al, 7
skip:
add al, '0'
mov [hexbuf + 3], al
mov al, ah
shr al, 4
and al, 0Fh
cmp al, 9
jna skip2
add al, 7
skip2:
add al, '0'
mov [hexbuf + 2], al
mov edx, hexbuflen
mov ecx, hexbuf
mov ebx, 1
mov eax, 4
int 80h
jmp looptop
done:
push 10
mov ecx, esp
mov edx, 1
mov ebx, 1
mov eax, 4
int 80h
add esp, 4
mov eax, 1
xor ebx, ebx
int 80h
;-----------------
global _start
section .data
msg db "Hello World", 0
hexbuf db "0xXX, "
hexbuflen equ $ - hexbuf
section .text
_start:
mov esi, msg
looptop:
mov al, [esi]
test al, al
jz done
inc esi
mov ah, al
and al, 0Fh
cmp al, 9
jna skip
add al, 7
skip:
add al, '0'
mov [hexbuf + 3], al
mov al, ah
shr al, 4
and al, 0Fh
cmp al, 9
jna skip2
add al, 7
skip2:
add al, '0'
mov [hexbuf + 2], al
mov edx, hexbuflen
mov ecx, hexbuf
mov ebx, 1
mov eax, 4
int 80h
jmp looptop
done:
push 10
mov ecx, esp
mov edx, 1
mov ebx, 1
mov eax, 4
int 80h
add esp, 4
mov eax, 1
xor ebx, ebx
int 80h
;-----------------