所以,这是一个恼人的问题: [最后一行包含问题,剩下的内容是更好地理解要求的背景。]
在汇编中,我们可以轻松使用printf函数来显示内容..它会自动将二进制数据正确转换为字符。
现在,在我的作业中,我需要使用十六进制数字并准确显示10个这样的数字之和。 我已经使用代码完成了分类并将ascii转换为十六进制数字(存储在半字节/ 4位中):
声明:
1)esi寄存器包含必须保存号码的存储位置。
2)temp是一个5字节的缓冲区,假设最多可以输入4个字符。
in: ; loop to take one multidigit input
mov ebx, 1 ;set error flag
scan temp, 5 ;take input
mov ecx, [temp]
mov edi, 4 ;assumes 4 digit input, works for 0 to 4 digit input
test: ;a validation check for input!!
cmp cl, 0Dh ;if current byte contains '\r'
je hop ;skip it
test0:
cmp cl, 030H ;cl >= '0'
jge test9 ;if yes, check if cl is digit
xor ebx, ebx ;otherwise, set error signal
jmp cont
test9:
cmp cl, 039h ;cl <= '9'
jle cont ;if yes, cl is a digit, case closed
jmp test10c ;otherwise, check if cl has hex character
test10c: ;for caps 'A'
cmp cl, 041h ;cl >= 10 (in caps char hex)
jge test15c ;if yes, check if cl is a caps hex character
xor ebx, ebx ;otherwise, set error signal
jmp cont
test15c:
cmp cl, 046h ;cl <= 15 (in hex)
jle conv ;if yes, cl is a caps hex character, case closed
jmp test10s ;otherwise check if cl has small hex character
test10s:
cmp cl, 061h ;cl >= 10 (in small char hex)
jge test15s ;if yes, check if cl is a small hex character
xor ebx, ebx ;otherwise, set error signal
jmp cont
test15s:
cmp cl, 066h ;cl <= 15 (in small char hex)
jle cont ;if yes, cl is a small hex character, case closed
xor ebx, ebx ;otherwise, set error signal
cont:
cmp ebx, 1 ;check for error
jne err ;if error, jump to err (abort loop)
jmp hop ;otherwise continue to next ascii character entered
hop:
rol ecx, 8 ;roll next character into cl
dec edi ;there are only 4 roll-in operations until you repeat the number
jnz test ;loop back to testing
end:
mov dword[temp], ecx ;store number between call
call conv ;convert number
mov ecx, [temp] ;take converted number
mov dword[esi], ecx ;store it in array
mov dword[temp], 0 ;store success signal
jmp quit
err:
mov dword[temp], 0FFh ;store error signal
quit: ;return to caller
ret
conv: ; loop to convert one multidigit input to specific format
mov ecx, dword[temp] ;take number
mov edi, 4 ;set number of rotations
fix:
cmp cl, 0Dh ;check with '\r'
mov cl, 0 ;'\r' will be stored as 0, the numbers 0-15 will be stored as 1-16
jmp skip
cmp cl, 046h ;check with 'F'
jle digitize ;if less, convert caps character to digit
sub cl, 020h ;if more, convert small character to caps
digitize:
cmp cl, 039h ;check with '9'
jle norm ;if less, convert ascii digit to normal digit
sub cl, 07h ;if more, convert character to ascii digit
norm:
sub cl, 030h ;convert ascii digit to hex digit
add cl, 01h ;encode 0-15 as 1-16 to accomodate '\r'
skip:
rol ecx, 8 ;roll next character into cl
dec edi ;there are only 4 roll-in operations until you repeat the number
jnz fix
ret
这里以特定方式编码了数字。您可以建议另外增加加法算法的简单性。
最后,引用问题:
“如何使用sys_write(函数编号4)将这些编码数字的总和正确写入stdout(文件描述符1)?”
答案 0 :(得分:0)
虽然您似乎是在Linux下进行编码,但我选择提供十六进制格式化32位数字打印的例程,我只是在dos-box环境中将它们组合在一起。您需要使用与int 0x10, func E
不同的机制来打印输出的每个字符。您还需要更改堆栈帧的内容,以允许推入堆栈的vars默认为4个字节,而不是2.即bp + 4(bp + 2 * 2)变为bp + 8( bp + 2 * 4)和ret 4(ret 2 * 2)变为ret 8(ret 2 * 4)
您也可能选择忘记手动担心附加溢出和进位标记 - 处理器不需要手持它的东西如此微不足道。
xor ebx, ebx ; total = 0
mov eax, 300
add ebx, eax ; total = total + 300
mov eax, 200
add ebx, eax ; total = total + 200
; etc, etc
这种打印功能的流程图非常短。我建议你自己(手动)流程图代码,以帮助澄清你的算法。
首先,代码:
[section .text]
[bits 16]
EntryPoint:
push long 0xDEADBEEF
call printHexLong
; print CRLF
mov ah, 0xe
mov al, 10
int 0x10
mov al, 13
int 0x10
push long 3735928559
call printHexLong
ret
;void printHexLong(ulong32 num)
printHexLong
push bp
mov bp, sp
mov ebx, [bp+4] ; get the input var
mov cx, 8 ; number of nibbles to do
.printLoop:
rol ebx, 4 ; 0x11223344 becomes 0x12233441
mov al, bl ; al = 0x41
and al, 0xF ; al = 0x01
cmp al, 10 ; will this nibble be 0..9 or will it be A..F ?
jb .oneToNine
sub al, 10 ; nibble is > 9, so it's A..F - subtract 10 so it's 0..9,
add al, 'A' ; then add ascii value of 'A'
jmp .outputNibble
.oneToNine:
add al, '0' ; nibble is < 10, so it's a digit 0..9
.outputNibble:
mov ah, 0xe ; video bios int - output a single character in teletype mode
int 0x10 ; output the nibble
dec cx ; decrement nibble counter
jnz .printLoop ; any left? If so, go again.
pop bp ; restore original value of bp
ret 4 ;remove the input var from the stack
现在输出:
DEADBEEF
DEADBEEF