我一直在阅读为了让寄存器执行整数/浮点除法,执行的寄存器实际上需要initialized
。我很好奇正确的汇编程序指令是做什么的。我只是通过以下内容提供地址:
mov ecx, 0x65F ;0x65F represents an address for ecx to point to
。
然后及时(稍后在代码中)做类似的事情:
mov byte [ecx], 0xA ;move the value of 0xA into the contents of ecx, using only a byte's worth of data
这是执行此类操作的正确方法吗?如果没有,那是什么?
更新
好的,所以我要做的就是将两个值相乘并将它们打印到屏幕上。
代码如下,由于某种原因,每当我尝试划分edx
时,我会得到分段错误或浮点算术异常。有人可以向我解释我做错了什么吗?
代码
section .data
counter: db 0xA ;store value 10 in 'counter', while allocating only one byte. This will be used for decrementing purposes
section .bss
valueToPrint: resb 4 ;alloc 4 bytes of data in 'valueToPrint'
section .text
global _start
_print_char:
add eax, '0' ;convert to ascii
mov [valueToPrint], eax ;store contents of 'eax' in valueToPrint
mov eax, 4 ;syswrite
mov ebx, 1 ;stdout
mov ecx, valueToPrint ;machine will take whatever value exists in 'ecx' and print
mov edx, 1 ;print only a single byte's worth of data
int 0x80 ;invoke kernel to perfrom instruction
ret
_convert_values:
mov edx, 0xA ;dividing eax by 10, which will lower its tens place
div edx ;(**Program crash here**)do division: remainder SHOULD be stored in edx
mov byte [edx], 0x0 ;zero out edx
call _print_char ;do printing for latest character
dec byte [counter] ;decrement counter
mov dword [eax], counter ;store counter in eax
jnz _convert_values ;while eax > 0 continue process
_endl:
mov eax, '\n' ;store newline character in eax to be printed
call _print_char ;print value
ret
_mul:
mov eax, 0x2A ;store 42 in eax
mov edx, 0x2B ;store 43 in edx
mul edx ;multiply [eax] * [edx]
ret
_safe_exit:
mov eax, 1 ;initiate 'exit' syscall
mov ebx, 0 ;exit with error code 0
int 0x80 ;invoke kernel to do its bidding
_start:
nop ;used to keep gdb from complaining
call _mul ;multiply the values
call _convert_values ;do hex to ascii conversion
jmp _safe_exit ;use jmp as opposed to call since it technically doesn't 'ret'
答案 0 :(得分:4)
我们在聊天中分别发言....
这是一个可以使用的工作版本。
它有一个微妙的问题。你能找到吗? 你能解释它为什么做它的作用吗?
; Multiply two numbers, display in ascii/decimal
;
; (because I have a 64bit system, this forces 32bit code)
bits 32
;
section .text
;
; _start is the ONLY label you MUST prepend _
; others might be library functions (ex: _printf,_exit)
; pure assembly only needs _start, if linked with glibc
; typically need _main INSTEAD of _start
;
global _start
;
;
_start:
nop ;placeholder for gdb's debug interrupt
;
call mul ;multiply the values
call convert_values ;do hex to ascii conversion
;
jmp safe_exit ;use jmp as opposed to call since it technically doesn't 'ret'
;
;
; subroutines / functions follow
;
mul:
mov eax, 0x2A ;store 42 in eax
mov edx, 0x2B ;store 43 in edx (42*43=1806)
mul edx ;multiply eax*edx, result in edx:eax
ret
;
; this routine doesn't handle BIG values from 'mul' which extend into edx
; we're learning, don't make things multiply out to more than 4.2 billion-ish
convert_values:
mov edx,0 ;value actually edx:eax, zero edx
mov ecx,0x0A ;divide edx:eax by 10
idiv ecx ;result in eax, remainder in edx
push eax ;save value on stack
mov eax,edx ;put remainder (0-9) in eax
add eax,'0' ;convert value to ascii character
call print_char ;print the latest character
pop eax ;restore value
or eax,eax ;set flags based on eax value
jnz convert_values ;while eax != 0 continue process
;
; nasm doesn't convert \n into LF... just use 10, equivalent
endl:
mov eax, 10 ;store newline character in eax to be printed
call print_char ;print value
ret
;
print_char:
mov [valueToPrint], eax ;store contents of 'eax' in [valueToPrint]
mov eax, 4 ;syswrite
mov ebx, 1 ;stdout
mov ecx, valueToPrint ;machine will take whatever value exists in [ecx] and print
mov edx, 1 ;print only a single byte's worth of data
int 0x80 ;invoke kernel to perfrom instruction
ret
;
safe_exit:
mov eax,1 ;initiate 'exit' syscall
mov ebx,0 ;exit with error code 0
int 0x80 ;invoke kernel to do its bidding
;
; =====================================
section .bss
; this section is not allocated, just reserved.
; Automatically set to zero when program starts
;
; alloc 4 bytes of data in 'valueToPrint'
valueToPrint:
resd 1 ; 1 resd=4 resb (Dword/Byte)
;
;
扰流警报......
打印结果BACKWARDS!
要解决这个问题,我们必须重新设计如何获得数字 并在打印前存储。
我正在通过电子邮件直接发送给您,以及一些其他说明。